diff --git a/source/Cosmos.Build.Windows/BuildUC.xaml.cs b/source/Cosmos.Build.Windows/BuildUC.xaml.cs index f1b8d9ec0..166975ca5 100644 --- a/source/Cosmos.Build.Windows/BuildUC.xaml.cs +++ b/source/Cosmos.Build.Windows/BuildUC.xaml.cs @@ -19,34 +19,29 @@ using System.Windows.Threading; namespace Cosmos.Build.Windows { - public class BuildLogMessage { - public LogSeverityEnum Severity { get; set; } - public string Message { get; set; } - } - - public class BuildLogMessages : ObservableCollection { - public BuildLogMessages() { } - } - public partial class BuildUC : UserControl { public BuildUC() { InitializeComponent(); } - public bool Display(Builder aBuilder, DebugModeEnum aDebugMode, byte aComPort) { - IEnumerable xMessages = new BuildLogMessage[0]; - aBuilder.PreventFreezing += PreventFreezing; - aBuilder.DebugLog += DoDebugMessage; + protected Builder mBuilder; + + public void BeginBuild(Builder aBuilder, DebugModeEnum aDebugMode, byte aComPort) { + mBuilder = aBuilder; aBuilder.ProgressChanged += DoProgressMessage; - //try { - aBuilder.Compile(aDebugMode, aComPort); + aBuilder.CompileCompleted += new Action(aBuilder_CompileCompleted); + aBuilder.BeginCompile(aDebugMode, aComPort); + } - aBuilder.DebugLog -= DoDebugMessage; - aBuilder.ProgressChanged -= DoProgressMessage; - //} catch { - // return false; - //} - return true; + public event Action CompileCompleted; + + protected void aBuilder_CompileCompleted() { + Dispatcher.BeginInvoke( + (Action)delegate() { + mBuilder.ProgressChanged -= DoProgressMessage; + CompileCompleted.Invoke(); + } + ); } public void DoDebugMessage(LogSeverityEnum aSeverity, string aMessage) { @@ -55,16 +50,6 @@ namespace Cosmos.Build.Windows { } } - public void PreventFreezing() { - var xFrame = new DispatcherFrame(); - Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Input, new DispatcherOperationCallback(delegate(object aParam) - { - xFrame.Continue = false; - return null; - }), null); - Dispatcher.PushFrame(xFrame); - } - protected void ProgressMessageReceived(string aMsg) { listProgress.SelectedIndex = listProgress.Items.Add(aMsg); listProgress.ScrollIntoView(listProgress.Items[listProgress.SelectedIndex]); @@ -74,8 +59,10 @@ namespace Cosmos.Build.Windows { var xAction = (Action)delegate() { ProgressMessageReceived(aMessage); }; - Dispatcher.BeginInvoke(DispatcherPriority.Input, xAction); - PreventFreezing(); + // Do not use BeginInvoke - if BeginInvoke is used these stack up + // and continue to come in and tie up the main thread after the engine completes + // and the window is closed + Dispatcher.Invoke(DispatcherPriority.Input, xAction); } } diff --git a/source/Cosmos.Build.Windows/BuildUI.cs b/source/Cosmos.Build.Windows/BuildUI.cs index 5f1a02bde..b1f8f8245 100644 --- a/source/Cosmos.Build.Windows/BuildUI.cs +++ b/source/Cosmos.Build.Windows/BuildUI.cs @@ -28,16 +28,21 @@ namespace Cosmos.Build.Windows { } var xBuildUC = new BuildUC(); mMainWindow.LoadControl(xBuildUC); - if (xBuildUC.Display(mBuilder, mOptionsUC.DebugMode, mOptionsUC.ComPort) == false) { - return; - } + xBuildUC.CompileCompleted += new Action(BuildUC_CompileCompleted); + xBuildUC.BeginBuild(mBuilder, mOptionsUC.DebugMode, mOptionsUC.ComPort); } - - DebugWindow xDebugWindow = null; + } + + protected void BuildUC_CompileCompleted() { + mBuilder.Assemble(); + mBuilder.Link(); + // Debug Window is only displayed if Qemu + Debug checked // or if other VM + Debugport selected + DebugWindow xDebugWindow = null; if (!mOptionsUC.rdioDebugModeNone.IsChecked.Value) { xDebugWindow = new DebugWindow(); + if (mOptionsUC.DebugMode == DebugModeEnum.Source) { var xLabelByAddressMapping = ObjDump.GetLabelByAddressMapping( mBuilder.BuildPath + "output.bin" @@ -78,10 +83,13 @@ namespace Cosmos.Build.Windows { } else if (mOptionsUC.rdioUSB.IsChecked.Value) { mBuilder.MakeUSB(mOptionsUC.cmboUSBDevice.Text[0]); } - + // Show the debug Window later - if we show it earlier some of the stuff blocks the + // main thread for a bit and causes the debug window to visibly stick for a bit + // and then it has to play catch up for a while if (xDebugWindow != null) { xDebugWindow.Show(); } + // Need to close MainWindow after DebugWindow is shown since it is the main Window mMainWindow.Close(); } diff --git a/source/Cosmos.Build.Windows/Builder.cs b/source/Cosmos.Build.Windows/Builder.cs index f2de066fb..e3880f673 100644 --- a/source/Cosmos.Build.Windows/Builder.cs +++ b/source/Cosmos.Build.Windows/Builder.cs @@ -16,11 +16,13 @@ namespace Cosmos.Build.Windows { public class Builder { public string BuildPath; public readonly string ToolsPath; + public readonly string AsmPath; public readonly Engine Engine = new Engine(); public Builder() { BuildPath = GetBuildPath(); ToolsPath = BuildPath + @"Tools\"; + AsmPath = ToolsPath + @"asm\"; // MtW: leave this here, otherwise VS wont copy required dependencies! typeof(X86OpCodeMap).Equals(null); } @@ -31,10 +33,8 @@ namespace Cosmos.Build.Windows { /// path to the Build directory. /// /// Full path to the Build directory. - protected static string GetBuildPath() - { - try - { + protected static string GetBuildPath() { + try { string xResult = ""; RegistryKey xKey = Registry.CurrentUser.OpenSubKey(@"Software\Cosmos"); @@ -53,8 +53,7 @@ namespace Cosmos.Build.Windows { xResult = xResult.Substring(0, xPos) + @"Build\"; } - if (string.IsNullOrEmpty(xResult)) - { + if (string.IsNullOrEmpty(xResult)) { throw new Exception("Cannot find Cosmos build path either in the Registry or using current directory search."); } if (!xResult.EndsWith(@"\")) @@ -63,9 +62,7 @@ namespace Cosmos.Build.Windows { } return xResult; - } - catch (Exception E) - { + } catch (Exception E) { throw new Exception("Error while getting Cosmos Build Path!", E); } } @@ -109,26 +106,20 @@ namespace Cosmos.Build.Windows { Global.Call(ToolsPath + @"mkisofs.exe", @"-R -b isolinux.bin -no-emul-boot -boot-load-size 4 -boot-info-table -o ..\Cosmos.iso .", xPath); } - private void DoDebugLog(LogSeverityEnum aSeverity, string aMessage) { - if (DebugLog != null) { - DebugLog(aSeverity, aMessage); - } - } - - public event DebugLogHandler DebugLog; public event Action ProgressChanged; - + public event Action CompileCompleted; + protected void ThreadExecute(object aParam) { var xParam = (PassedEngineValue)aParam; Engine.Execute(xParam.aAssembly, xParam.aTargetPlatform, xParam.aGetFileNameForGroup , xParam.aInMetalMode, xParam.aPlugs, xParam.aDebugMode, xParam.aDebugComNumber , xParam.aOutputDir); + CompileCompleted.Invoke(); } - public void Compile(DebugModeEnum aDebugMode, byte aDebugComport) { - string xAsmPath = ToolsPath + @"asm\"; - if (!Directory.Exists(xAsmPath)) { - Directory.CreateDirectory(xAsmPath); + public void BeginCompile(DebugModeEnum aDebugMode, byte aDebugComport) { + if (!Directory.Exists(AsmPath)) { + Directory.CreateDirectory(AsmPath); } Assembly xTarget = System.Reflection.Assembly.GetEntryAssembly(); Engine.ProgressChanged += delegate() { @@ -136,31 +127,29 @@ namespace Cosmos.Build.Windows { ProgressChanged(Engine.ProgressMax, Engine.ProgressCurrent, Engine.ProgressMessage); } }; - Engine.DebugLog += DoDebugLog; - var xEngineParams = new PassedEngineValue(xTarget.Location, TargetPlatformEnum.X86, g => Path.Combine(xAsmPath, g + ".asm"), false, - new string[] { - Path.Combine(Path.Combine(ToolsPath, "Cosmos.Kernel.Plugs"), "Cosmos.Kernel.Plugs.dll"), - Path.Combine(Path.Combine(ToolsPath, "Cosmos.Hardware.Plugs"), "Cosmos.Hardware.Plugs.dll"), - Path.Combine(Path.Combine(ToolsPath, "Cosmos.Sys.Plugs"), "Cosmos.Sys.Plugs.dll") - }, aDebugMode, aDebugComport, xAsmPath); + var xEngineParams = new PassedEngineValue(xTarget.Location, TargetPlatformEnum.X86, g => Path.Combine(AsmPath, g + ".asm"), false + , new string[] { + Path.Combine(Path.Combine(ToolsPath, "Cosmos.Kernel.Plugs"), "Cosmos.Kernel.Plugs.dll"), + Path.Combine(Path.Combine(ToolsPath, "Cosmos.Hardware.Plugs"), "Cosmos.Hardware.Plugs.dll"), + Path.Combine(Path.Combine(ToolsPath, "Cosmos.Sys.Plugs"), "Cosmos.Sys.Plugs.dll") + } + , aDebugMode, aDebugComport, AsmPath); var xThread = new Thread(new ParameterizedThreadStart(ThreadExecute)); xThread.Start(xEngineParams); - while (xThread.IsAlive) { - Thread.Sleep(25); - PreventFreezing(); - } - + } + + public void Assemble() { RemoveFile(BuildPath + "output.obj"); - Global.Call(ToolsPath + @"nasm\nasm.exe", String.Format("-g -f elf -F stabs -o \"{0}\" \"{1}\"", BuildPath + "output.obj", xAsmPath + "main.asm"), BuildPath); - + Global.Call(ToolsPath + @"nasm\nasm.exe", String.Format("-g -f elf -F stabs -o \"{0}\" \"{1}\"", BuildPath + "output.obj", AsmPath + "main.asm"), BuildPath); + } + + public void Link() { RemoveFile(BuildPath + "output.bin"); Global.Call(ToolsPath + @"cygwin\ld.exe", String.Format("-Ttext 0x500000 -Tdata 0x200000 -e Kernel_Start -o \"{0}\" \"{1}\"", "output.bin", "output.obj"), BuildPath); RemoveFile(BuildPath + "output.obj"); } - public event Action PreventFreezing; - public void MakeVPC() { MakeISO(); string xPath = BuildPath + @"VPC\"; diff --git a/source/Cosmos.Build.Windows/OptionsUC.xaml.cs b/source/Cosmos.Build.Windows/OptionsUC.xaml.cs index e2c32f494..789de20d0 100644 --- a/source/Cosmos.Build.Windows/OptionsUC.xaml.cs +++ b/source/Cosmos.Build.Windows/OptionsUC.xaml.cs @@ -62,11 +62,8 @@ namespace Cosmos.Build.Windows { public Action Proceed; public Action Stop; - - private void butnBuild_Click(object sender, RoutedEventArgs e) { - if (mSaveSettings) { - SaveSettingsToRegistry(); - } + + protected void UpdateProperties() { mComPort = (byte)cmboDebugPort.SelectedIndex; if (mComPort > 3) { throw new Exception("Debug port not supported yet!"); @@ -83,6 +80,13 @@ namespace Cosmos.Build.Windows { } else { throw new Exception("Unknown debug mode."); } + } + + private void butnBuild_Click(object sender, RoutedEventArgs e) { + if (mSaveSettings) { + SaveSettingsToRegistry(); + UpdateProperties(); + } Proceed(); } @@ -117,6 +121,8 @@ namespace Cosmos.Build.Windows { cmboAudioCards.Items.Add(xSoundCard); } LoadSettingsFromRegistry(); + // Call here for when this dialog is bypassed, others read these values + UpdateProperties(); } void OptionsUC_Loaded(object sender, RoutedEventArgs e) {