//--------------------------------------------------------------------------------------------------------------------------------------------------- // // Copyright (C)2007 DarkWynter Studios. All rights reserved. // //--------------------------------------------------------------------------------------------------------------------------------------------------- // {Contact : darkwynter.com for licensing information //--------------------------------------------------------------------------------------------------------------------------------------------------- namespace DarkWynter.App { #region Using Statements using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Reflection; using System.CodeDom.Compiler; using System.CodeDom; using System.IO; using System.Xml; using Microsoft.Xna; using Microsoft.Xna.Framework; using DarkWynter.Stream; using DarkWynter.Engine.Globals; using DarkWynter.Engine.Utilities; using DarkWynter.Engine.EventControl; using DarkWynter.Engine.GameObjects; using DarkWynter.App.Surveys; //using DarkWynter.App.ChallengeSet; using System.Threading; //using CSTextEditor; using DarkWynter.App.ChallengeSet; //using CSTextEditor; #endregion /// /// The compiler form /// public partial class CompilerControl : UserControl { public static CompilerControl compilerControl; public static List challengeList; public static MenuStrip menuStripPointer; public static ToolStripMenuItem refreshPointer; CompilerResults compilerResults; //PrettyCompilerControl prettyCompilerControl; public static RichTextBox richTextBox_CodeWindow; int unsuccessfulCompiles = 0; public static string customErrorMessage; public static string studentCode; string cleanedStudentCode; bool docked = true; public delegate void Output_EventHandler(string message); /// /// CompilerControl constructor /// public CompilerControl() { InitializeComponent(); this.Dock = DockStyle.Fill; menuStripPointer = menuStrip1; CompilerControl.richTextBox_CodeWindow = this.codeTextBox; compilerControl = this; LoadChallenges("_xml//QuestSettings//WhileLoops.xml"); Engine.DarkWynterEngine.onLevelChange += new DarkWynter.Engine.DarkWynterEngine.OnLevelChange(this.Load_OnLevelChange); } public void Load_OnLevelChange(EventArgs e) { Statics_Engine.GameSettings.isProblemFinished = true; resetText(); } /// /// Loads the challenges from XML /// private void LoadChallenges(string questSettingsFilePath) { // Read the Quest File List ChallengeNodes = new List(); try { XmlDocument reader = new XmlDocument(); reader.Load(questSettingsFilePath); // Get all outer nodes (incl xml version info and level) XmlNodeList allNodes = reader.ChildNodes; foreach (XmlNode questNode in allNodes) { // If level definition if (questNode.Name == "QuestSet") { foreach (XmlNode problemSetNode in questNode) { // Post problems for GameForm to access if (problemSetNode.Name == "ProblemSet") { ChallengeNodes.Add(problemSetNode); } } } } } // Catch all loading exceptions and print message to user. catch (Exception e) { MessageBox.Show(e.Message); DarkWynter.Engine.DarkWynterEngine.ContentInstall_WarningMessage(); } challengeList = new List(); for (int i = 0; i < ChallengeNodes.Count; i++) { if (int.Parse(ChallengeNodes[i].Attributes["id"].Value) == 0) { challengeList.Add(new Challenge0(ChallengeNodes[i])); } if (int.Parse(ChallengeNodes[i].Attributes["id"].Value) == 1) { challengeList.Add(new Challenge1(ChallengeNodes[i])); } if (int.Parse(ChallengeNodes[i].Attributes["id"].Value) == 2) { challengeList.Add(new Challenge2(ChallengeNodes[i])); } if (int.Parse(ChallengeNodes[i].Attributes["id"].Value) == 3) { challengeList.Add(new Challenge3(ChallengeNodes[i])); } } // Init first problem Statics_Engine.GameSettings.currentChallengeNumber = DarkWynter.Engine.Globals.Statics_Engine.levelIndex; // Load the first problem codeTextBox.Text = challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding(); } #region Compile and Run the code public string CompileCodeWithOutput() { CompileCode(); return outputTextBox.Text; } /// /// Compiles the code in the codeTextBox.Text field /// public void CompileCode() { try { Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Button Message] Student hit compiler button [End Button Message]"); Logging.G2LLogList.Add("\r\n[Student Code] - \r\n"); Logging.G2LLogList.Add(cleanedStudentCode + "\r\n[End Student Code]\r\n"); compilerResults = DarkWynter.Engine.Compiler.CSharpCompiler.CompileCode(studentCode); // If _does_not_ compile if (compilerResults.Errors.HasErrors == true) { // Display compilation errors. StringBuilder sb = new StringBuilder(); sb.AppendFormat("Errors building {0} into {1}\n\n", studentCode, compilerResults.PathToAssembly); foreach (CompilerError ce in compilerResults.Errors) { sb.Append(ce.ToString()); sb.Append("\n"); } unsuccessfulCompiles++; GameEventHandler.CurrentGameConditions.triggerSanity = 11; outputTextBox.Text = sb.ToString(); Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Error Message] There were errors in the code [End Error Message] "); Logging.G2LLogList.Add(sb.ToString()); Logging.G2LLogList.Add(" [Record Message] This is the " + unsuccessfulCompiles + " attempt at this problem. [End Record Message] "); } if (compilerResults.Errors.HasErrors == false) { outputTextBox.Text = "Compile Successful\n"; Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Success Message] There were no errors in the code [End Success Message] "); } // Update Pretty Compiler Output box //OutputChanged(outputTextBox.Text); } catch (Exception ex) { MessageBox.Show("Hey bro.. \nTry loading the level before compiling.. \nSee the Level Editor tab.."); } } /// /// Runs the compiled code /// /// /// private void runToolStripMenuItem_Click(object sender, EventArgs e) { RunCode(); } /// /// Runs the Code, after compilation, in the codeTextBoc.Text field /// public void RunCode() { // If it hasn't been compiled, just have them compile it if (compilerResults == null) { outputTextBox.Text = "You must compile before you can run!"; Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Error Message] Student tried to run without compiling first. [End Error Message]"); return; } // If compiles, validate output if (compilerResults.Errors.Count == 0) { StringWriter stringWriter = new StringWriter(); Console.SetOut(stringWriter); // Execute user code DarkWynter.Engine.Compiler.CSharpCompiler.Execute(compilerResults.CompiledAssembly, "Test", "MyFunction", null); // List output in compiler feedback box try { outputTextBox.Text += stringWriter.ToString(); Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Compiler output] - "); Logging.G2LLogList.Add(stringWriter.ToString() + "[End Compiler output]\r\n"); // Execute instructor evaluation and feedback function if (challengeList[Statics_Engine.GameSettings.currentChallengeNumber].ValidateStudentCode(studentCode, stringWriter.ToString())) { if (Statics_Engine.GameSettings.isProblemFinished == false) { // Set the statics for the HUD to use to run the actual visualization while the code runs for the student // Statics_Engine.GameSettings.ParsesandCompilesCode = studentCode; // If correct, call the vis code challengeList[Statics_Engine.GameSettings.currentChallengeNumber].RunVizualization(); Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Success Message] Bridge " + Statics_Engine.GameSettings.currentChallengeNumber + " built successfully. [End Success Message]"); // Ensure Current Prob does not go out of bounds if (Statics_Engine.GameSettings.currentChallengeNumber < challengeList.Count - 1) { // Finish the vis and don't run it again Statics_Engine.GameSettings.isProblemFinished = true; Statics_Engine.GameSettings.currentChallengeNumber++; } } } // write the custom error message to the screen and to the log else outputTextBox.Text = customErrorMessage; Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Custom Error Message] " + customErrorMessage + " [End Custom Error Message]"); } catch (NullReferenceException x) { outputTextBox.Text = x.ToString(); Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Compiler output] - "); // Logging.G2LLogList.Add(runOnWhile + "[End Compiler output]\r\n"); } // Move the scroller down ScrolltoText(); stringWriter.Close(); //resetText(); } // Update Pretty Compiler Output box //OutputChanged(outputTextBox.Text); } #endregion #region Buttons, buttons, and more buttons /// /// Open the form, deactivates Engine controls, resize the gameWindow, handle resetText() trigger /// /// /// private void openToolStripMenuItem_Click(object sender, EventArgs e) { Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Button Message] Compiler panels opened [End Button Message]"); Logging.G2LLogList.Add("\r\n[Game Message] Student is on problem number " + Statics_Engine.GameSettings.currentChallengeNumber); Logging.G2LLogList.Add("Student is on island number " + Statics_Engine.GameSettings.currentChallengeNumber + " [End Game Message] \r\n"); Engine.DarkWynterEngine.Deactivate(); //compilerPanel.Show(); //dialogueGroupPanel.Show(); // getTMLoc.Show(); //getTMLoc.Enabled = true; if (Statics_Engine.PlayerSettings.doResetText == true) { resetText(); } //int GameWindowWidth = 620; //int GameWindowHeight = 500; //GameForm.dwGameControl.Location = new System.Drawing.Point(400, 55); //GameForm.dwGameControl.Size = new System.Drawing.Size(GameWindowWidth, GameWindowHeight); // Set the viewport Microsoft.Xna.Framework.Graphics.Viewport viewport = new Microsoft.Xna.Framework.Graphics.Viewport(); //viewport.X = GameForm.dwGameControl.Location.X; //viewport.Y = GameForm.dwGameControl.Location.Y; //viewport.Width = GameForm.dwGameControl.Size.Width; //viewport.Height = GameForm.dwGameControl.Size.Height; viewport.MinDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MinDepth; viewport.MaxDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MaxDepth; Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport = viewport; } /// /// Reactivates Engine controls, resets gameWindow /// /// /// private void closeCompilerToolStripMenuItem1_Click(object sender, EventArgs e) { Logging.G2LLogList.Add(DateTime.Now.ToString() + " - [Button Message] Compiler panels closed [End Button Message] "); Engine.DarkWynterEngine.Activate(); //compilerPanel.Hide(); //dialogueGroupPanel.Hide(); //compileButton.Hide(); //runButton.Hide(); // getTMLoc.Hide(); // getTMLoc.Enabled = false; //GameForm.dwGameControl.Location = new System.Drawing.Point(0, 25); //GameForm.dwGameControl.Size = new System.Drawing.Size(1024, 743); // Set the viewport Microsoft.Xna.Framework.Graphics.Viewport viewport = new Microsoft.Xna.Framework.Graphics.Viewport(); //viewport.X = GameForm.dwGameControl.Location.X; //viewport.Y = GameForm.dwGameControl.Location.Y; //viewport.Width = GameForm.dwGameControl.Size.Width; //viewport.Height = GameForm.dwGameControl.Size.Height; viewport.MinDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MinDepth; viewport.MaxDepth = Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport.MaxDepth; Statics_Stream.RenderSettings.graphics.GraphicsDevice.Viewport = viewport; } /// /// Will save out to a text file when I finish it /// /// /// private void saveButton_Click(object sender, EventArgs e) { // save the code out String name = "problem" + Statics_Engine.GameSettings.currentChallengeNumber + ".txt"; string logFile = "../../../__Game/Compiler/Logs/" + name; StreamWriter myFile = null; FileStream fileStream = File.Open(logFile, FileMode.CreateNew, FileAccess.Write); myFile = new StreamWriter(fileStream); myFile.WriteLine(DateTime.Now); myFile.Write(codeTextBox.Text); //myFile.Write(compilerExternalForm.textEditorControl1.Text); myFile.Close(); } /// /// Activate Compiler /// /// /// private void compileToolStripMenuItem_Click(object sender, EventArgs e) { // Compile student code studentCode = codeTextBox.Text; cleanedStudentCode = studentCode.Trim(); cleanedStudentCode = studentCode.Replace('\n', ' '); CompileCode(); } /// /// Refreshes to the next code set /// /// /// public void refreshToolStripMenuItem_Click(object sender, EventArgs e) { if (Statics_Engine.GameSettings.isProblemFinished == true) { Statics_Engine.GameSettings.currentChallengeNumber++; resetText(); resetText(); } else resetText(); } #endregion #region Helper methods // autoscoll boxNumber keeps track of which one we are changing public void ScrolltoText() { outputTextBox.SelectionStart = outputTextBox.Text.Length; outputTextBox.ScrollToCaret(); outputTextBox.Select(); } /// /// Resets all the text boxes back to initial state /// public void resetText() { // Reset dialog counter in problem challengeList[Statics_Engine.GameSettings.currentChallengeNumber].dialogueCounter = 0; // Clear boxes //InstructionControl.dialogTextBoxPointer.Text = ""; outputTextBox.Text = ""; codeTextBox.Text = ""; // Load the problem codeTextBox.Text = challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding(); // External Form //compilerExternalForm.textEditorControl1.Text = //challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding(); //// Load the first instructions //InstructionControl.dialogTextBoxPointer.Text += // challengeList[Statics_Engine.GameSettings.currentChallengeNumber] // .challengeDialogue[challengeList[Statics_Engine.GameSettings.currentChallengeNumber].dialogueCounter] + "\r\n"; Statics_Engine.GameSettings.isProblemFinished = false; } #endregion #region External Compiler private void cSCompilerToolStripMenuItem_Click(object sender, EventArgs e) { // Form thread Thread t = new Thread(new ThreadStart(compilerForm)); t.SetApartmentState(ApartmentState.STA); t.Start(); } //[MTAThread] /// /// /// private void compilerForm() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); //prettyCompilerControl = new PrettyCompilerControl(); //prettyCompilerControl.compileToolStripMenuItem.Click += new System.EventHandler(this.compileToolStripMenuItem_Click); //prettyCompilerControl.debugToolStripMenuItem.Click += new System.EventHandler(this.runToolStripMenuItem_Click); //prettyCompilerControl.textEditorControl1.Text = // challengeList[Statics_Engine.GameSettings.currentChallengeNumber].GetScaffolding(); //Application.Run(prettyCompilerControl); //compilerForm.MinimizeBox = false; //compilerForm.MaximizeBox = false; //compilerForm.FormBorderStyle = FormBorderStyle.Sizable; //compilerForm.Show(); } private void undockToolStripMenuItem_Click(object sender, EventArgs e) { if (docked) { DarkWynter.Shell.UCAD._UCAD_ChildForm.Controls.Clear(); DarkWynter.Shell.UCAD._UCAD_ChildForm.Controls.Add(this); DarkWynter.Shell.UCAD._UCAD_ChildForm.Name = "CompilerForm"; DarkWynter.Shell.UCAD._UCAD_ChildForm.Text = "Compiler Form"; DarkWynter.Shell.UCAD._UCAD_ChildForm.WindowState = FormWindowState.Maximized; DarkWynter.Shell.UCAD._UCAD_ChildForm.ControlBox = false; DarkWynter.Shell.UCAD._UCAD_ChildForm.MaximizeBox = false; DarkWynter.Shell.UCAD._UCAD_ChildForm.MinimizeBox = false; DarkWynter.Shell.UCAD._UCAD_ChildForm.ResumeLayout(false); DarkWynter.Shell.UCAD._UCAD_ChildForm.Show(); DarkWynter.Shell.UCAD.LeftPanelCollapse(); undockToolStripMenuItem.Text = "Dock"; docked = false; } else { DarkWynter.Shell.UCAD._UCAD_Left_Panel.Controls.Clear(); DarkWynter.Shell.UCAD._UCAD_Left_Panel.Controls.Add(this); DarkWynter.Shell.UCAD._UCAD_ChildForm.Hide(); DarkWynter.Shell.UCAD.LeftPanelExpand(); //UCADInterfaceControl._UCAD_Self.UCAD_Left_SplitContainer.Panel1Collapsed = true; undockToolStripMenuItem.Text = "Undock"; docked = true; } } ///// ///// The main entry point for the application. ///// //[STAThread] //static void RunCompilerForm() //{ // Application.EnableVisualStyles(); // Application.SetCompatibleTextRenderingDefault(false); // Application.Run(new MainForm()); //} #endregion } }