diff --git a/ShiftOS.WinForms/Applications/MindBlow.Designer.cs b/ShiftOS.WinForms/Applications/MindBlow.Designer.cs index ad2304d..6a8474d 100644 --- a/ShiftOS.WinForms/Applications/MindBlow.Designer.cs +++ b/ShiftOS.WinForms/Applications/MindBlow.Designer.cs @@ -32,16 +32,16 @@ this.console = new System.Windows.Forms.TabPage(); this.consoleout = new System.Windows.Forms.TextBox(); this.program = new System.Windows.Forms.TabPage(); + this.stop = new System.Windows.Forms.Button(); this.run = new System.Windows.Forms.Button(); this.save = new System.Windows.Forms.Button(); this.load = new System.Windows.Forms.Button(); this.programinput = new System.Windows.Forms.TextBox(); this.monitor = new System.Windows.Forms.TabPage(); + this.reset = new System.Windows.Forms.Button(); this.memlist = new System.Windows.Forms.ListBox(); this.instptr = new System.Windows.Forms.Label(); this.memptr = new System.Windows.Forms.Label(); - this.stop = new System.Windows.Forms.Button(); - this.reset = new System.Windows.Forms.Button(); this.tabs.SuspendLayout(); this.console.SuspendLayout(); this.program.SuspendLayout(); @@ -79,6 +79,7 @@ this.consoleout.Multiline = true; this.consoleout.Name = "consoleout"; this.consoleout.ReadOnly = true; + this.consoleout.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.consoleout.Size = new System.Drawing.Size(378, 237); this.consoleout.TabIndex = 0; // @@ -97,6 +98,16 @@ this.program.Text = "Program"; this.program.UseVisualStyleBackColor = true; // + // stop + // + this.stop.Location = new System.Drawing.Point(303, 217); + this.stop.Name = "stop"; + this.stop.Size = new System.Drawing.Size(75, 23); + this.stop.TabIndex = 4; + this.stop.Text = "Stop"; + this.stop.UseVisualStyleBackColor = true; + this.stop.Click += new System.EventHandler(this.stop_Click); + // // run // this.run.Location = new System.Drawing.Point(196, 217); @@ -132,6 +143,7 @@ this.programinput.Location = new System.Drawing.Point(3, 0); this.programinput.Multiline = true; this.programinput.Name = "programinput"; + this.programinput.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.programinput.Size = new System.Drawing.Size(378, 218); this.programinput.TabIndex = 0; // @@ -148,6 +160,17 @@ this.monitor.Text = "Monitor"; this.monitor.UseVisualStyleBackColor = true; // + // reset + // + this.reset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.reset.Location = new System.Drawing.Point(306, 8); + this.reset.Name = "reset"; + this.reset.Size = new System.Drawing.Size(75, 23); + this.reset.TabIndex = 3; + this.reset.Text = "Reset"; + this.reset.UseVisualStyleBackColor = true; + this.reset.Click += new System.EventHandler(this.reset_Click); + // // memlist // this.memlist.FormattingEnabled = true; @@ -176,27 +199,6 @@ this.memptr.TabIndex = 0; this.memptr.Text = "Memory: 0"; // - // stop - // - this.stop.Location = new System.Drawing.Point(303, 217); - this.stop.Name = "stop"; - this.stop.Size = new System.Drawing.Size(75, 23); - this.stop.TabIndex = 4; - this.stop.Text = "Stop"; - this.stop.UseVisualStyleBackColor = true; - this.stop.Click += new System.EventHandler(this.stop_Click); - // - // reset - // - this.reset.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.reset.Location = new System.Drawing.Point(306, 8); - this.reset.Name = "reset"; - this.reset.Size = new System.Drawing.Size(75, 23); - this.reset.TabIndex = 3; - this.reset.Text = "Reset"; - this.reset.UseVisualStyleBackColor = true; - this.reset.Click += new System.EventHandler(this.reset_Click); - // // MindBlow // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); diff --git a/ShiftOS.WinForms/Applications/MindBlow.cs b/ShiftOS.WinForms/Applications/MindBlow.cs index 4fcda03..54167da 100644 --- a/ShiftOS.WinForms/Applications/MindBlow.cs +++ b/ShiftOS.WinForms/Applications/MindBlow.cs @@ -10,6 +10,8 @@ using System.Windows.Forms; using ShiftOS.Engine; using System.IO; using System.Threading; +using System.Collections; +using System.Collections.Concurrent; namespace ShiftOS.WinForms.Applications { @@ -18,6 +20,12 @@ namespace ShiftOS.WinForms.Applications [RequiresUpgrade("mindblow")] public partial class MindBlow : UserControl, IShiftOSWindow, IBFListener { + private bool running = true; + private Action updateMemPtr = null, updateIPtr = null; + private Action[] updateMem = new Action[30000]; + private AutoResetEvent evwaiting = new AutoResetEvent(false); + private object evlock = new object(); + private class TextBoxStream : Stream { private TextBox box; @@ -54,26 +62,20 @@ namespace ShiftOS.WinForms.Applications public override int Read(byte[] buffer, int offset, int count) { - object lck = new object(); int ptr = offset; + var hnd = new AutoResetEvent(false); handler = (o, a) => { - lock (lck) + if (ptr < offset + count) { - if (ptr < offset + count) - { - buffer[ptr] = (byte)a.KeyChar; - ptr++; - } + buffer[ptr] = (byte)a.KeyChar; + ptr++; } + if (ptr >= offset + count) + hnd.Set(); }; Desktop.InvokeOnWorkerThread(() => box.KeyPress += handler); - while (true) - { - lock (lck) - if (ptr >= offset + count) - break; - } + hnd.WaitOne(); Desktop.InvokeOnWorkerThread(() => box.KeyPress -= handler); return count; } @@ -129,12 +131,23 @@ namespace ShiftOS.WinForms.Applications public void IPtrMoved(int newval) { - Desktop.InvokeOnWorkerThread(() => instptr.Text = "Instruction: " + newval.ToString()); + lock (evlock) + { + updateIPtr = () => instptr.Text = "Instruction: " + newval.ToString(); + evwaiting.Set(); + } } public void MemChanged(ushort pos, byte newval) { - Desktop.InvokeOnWorkerThread(() => memlist.Items[pos] = newval.ToString()); + lock (evlock) + { + updateMem[pos] = () => + { + memlist.Items[pos] = newval.ToString(); + }; + evwaiting.Set(); + } } public void MemReset() @@ -149,6 +162,36 @@ namespace ShiftOS.WinForms.Applications public void OnLoad() { DoLayout(); + new Thread(() => + { + while (running) + { + evwaiting.WaitOne(); + try + { + lock (evlock) + { + if (updateIPtr != null) + { + Desktop.InvokeOnWorkerThread(updateIPtr); + updateIPtr = null; + } + if (updateMemPtr != null) + { + Desktop.InvokeOnWorkerThread(updateMemPtr); + updateMemPtr = null; + } + for (int i = 0; i < updateMem.Length; i++) + if (updateMem[i] != null) + { + Desktop.InvokeOnWorkerThread(updateMem[i]); + updateMem[i] = null; + } + } + } catch { } + evwaiting.Reset(); + } + }).Start(); } public void OnSkinLoad() @@ -157,6 +200,9 @@ namespace ShiftOS.WinForms.Applications public bool OnUnload() { + running = false; + evwaiting.Set(); // allow the display loop to die of old age + KillThread(); // mercilessly slaughter the interpreter thread return true; } @@ -166,7 +212,11 @@ namespace ShiftOS.WinForms.Applications public void PointerMoved(ushort newval) { - Desktop.InvokeOnWorkerThread(() => memptr.Text = "Memory: " + newval.ToString()); + lock (evlock) + { + updateMemPtr = () => memptr.Text = "Memory: " + newval.ToString(); + evwaiting.Set(); + } } private void MindBlow_Resize(object sender, EventArgs e) @@ -207,7 +257,7 @@ namespace ShiftOS.WinForms.Applications AppearanceManager.SetupDialog(new FileDialog(new string[] { ".bf" }, FileOpenerStyle.Save, new Action((file) => Objects.ShiftFS.Utils.WriteAllText(file, programinput.Text)))); } - private void stop_Click(object sender, EventArgs e) + private void KillThread() { if (InterpreterThread != null) try @@ -215,7 +265,12 @@ namespace ShiftOS.WinForms.Applications InterpreterThread.Abort(); } catch { } - consoleout.KeyPress -= consolestr.handler; + consoleout.KeyPress -= consolestr.handler; + } + + private void stop_Click(object sender, EventArgs e) + { + KillThread(); } private void reset_Click(object sender, EventArgs e)