//--------------------------------------------------------------------------------------------------------------------------------------------------- // // 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.Init; using DarkWynter.Engine.Utilities; using DarkWynter.Engine.EventControl; using DarkWynter.Game; using DarkWynter.Engine.GameObjects; using DarkWynter.App.Surveys; using DarkWynter.App.ChallengeSet; using System.Threading; using CSTextEditor; //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; LoadChallenges(); //menuStrip1.Hide(); menuStripPointer = menuStrip1; CompilerControl.richTextBox_CodeWindow = this.codeTextBox; Engine.DarkWynterEngine.onLevelChange += new DarkWynter.Engine.DarkWynterEngine.OnLevelChange(this.Load_OnLevelChange); compilerControl = this; numberLabel.Font = new Font(codeTextBox.Font.FontFamily, codeTextBox.Font.Size - 0.0f); } public void Load_OnLevelChange(EventArgs e) { Statics_Engine.GameSettings.isProblemFinished = true; resetText(); } /// /// Loads the challenges from XML /// private void LoadChallenges() { #region Challenges // Create Challenge List challengeList = new List(); for (int i = 0; i < XML.ChallengeNodes.Count; i++) { if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 0) { challengeList.Add(new Challenge0(XML.ChallengeNodes[i])); } if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 1) { challengeList.Add(new Challenge1(XML.ChallengeNodes[i])); } if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 2) { challengeList.Add(new Challenge2(XML.ChallengeNodes[i])); } if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 3) { challengeList.Add(new Challenge3(XML.ChallengeNodes[i])); } if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 4) { challengeList.Add(new Challenge4(XML.ChallengeNodes[i])); } if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 5) { challengeList.Add(new Challenge5(XML.ChallengeNodes[i])); } if (int.Parse(XML.ChallengeNodes[i].Attributes["id"].Value) == 6) { challengeList.Add(new Challenge6(XML.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(); // Load the first instructions InstructionControl.dialogTextBoxPointer.Text += challengeList[Statics_Engine.GameSettings.currentChallengeNumber].challengeDialogue[challengeList[Statics_Engine.GameSettings.currentChallengeNumber].dialogueCounter] + "\r\n"; #endregion } #region Compile and Run the code public string CompileCodeWithOutput() { CompileCode(); return outputTextBox.Text; } /// /// Compiles the code in the codeTextBox.Text field /// public void CompileCode() { 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.Count > 0) { // 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.Count == 0) { 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); } /// /// 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(stringWriter.ToString()); 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; //HERE //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) { //HERE 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; } private void updateNumberLabel() { //we get index of first visible char and number of first visible line System.Drawing.Point pos = new System.Drawing.Point(0, 0); int firstIndex = codeTextBox.GetCharIndexFromPosition(pos); int firstLine = codeTextBox.GetLineFromCharIndex(firstIndex); //now we get index of last visible char and number of last visible line pos.X = ClientRectangle.Width; pos.Y = ClientRectangle.Height; int lastIndex = codeTextBox.GetCharIndexFromPosition(pos); int lastLine = codeTextBox.GetLineFromCharIndex(lastIndex); //this is point position of last visible char, we'll use its Y value for calculating numberLabel size pos = codeTextBox.GetPositionFromCharIndex(lastIndex); //finally, renumber label numberLabel.Text = ""; for (int i = firstLine; i <= lastLine + 1; i++) { numberLabel.Text += i + 1 + "\n"; } } private void codeTextBox_TextChanged(object sender, EventArgs e) { updateNumberLabel(); } private void codeTextBox_VScroll(object sender, EventArgs e) { //move location of numberLabel for amount of pixels caused by scrollbar int d = codeTextBox.GetPositionFromCharIndex(0).Y % (codeTextBox.Font.Height + 1); numberLabel.Location = new System.Drawing.Point(0, d); updateNumberLabel(); } private void codeTextBox_Resize(object sender, EventArgs e) { codeTextBox_VScroll(null, null); } private void richTextBox1_FontChanged(object sender, EventArgs e) { updateNumberLabel(); codeTextBox_VScroll(null, null); } #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) { UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Controls.Clear(); UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Controls.Add(this); UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Name = "CompilerForm"; UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Text = "Compiler Form"; UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.WindowState = FormWindowState.Maximized; UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.ControlBox = false; UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.MaximizeBox = false; UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.MinimizeBox = false; UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.ResumeLayout(false); UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Show(); UCADInterfaceControl._UCAD_Inteface.LeftPanelCollapse(); undockToolStripMenuItem.Text = "Dock"; docked = false; } else { UCADInterfaceControl._UCAD_Inteface.UCAD_Left_Panel.Controls.Clear(); UCADInterfaceControl._UCAD_Inteface.UCAD_Left_Panel.Controls.Add(this); UCADInterfaceControl._UCAD_Inteface.UCAD_ChildForm.Hide(); UCADInterfaceControl._UCAD_Inteface.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 } }