mirror of
https://git.alee14.me/shiftos-archive/ShiftOS_TheReturn.git
synced 2025-01-22 18:02:16 +00:00
made MindBlow wayyy faster
More threads. More responsive. The IBFListener calls don't wait for the WinForms updates to finish now. They put changes onto a few variables using a lock and then activate a dormant thread to actually run those on the worker thread. Once it's done, that dormant thread goes back to waiting for an AutoResetEvent to fire that tells it when there's actually work to do. So it shouldn't chew up any CPU. I found out about this object working on this project and now I want to find everywhere in the game that uses a while loop to wait for stuff, and replace it with this.
This commit is contained in:
parent
1c9d527ba0
commit
37e9af7ca6
2 changed files with 98 additions and 41 deletions
48
ShiftOS.WinForms/Applications/MindBlow.Designer.cs
generated
48
ShiftOS.WinForms/Applications/MindBlow.Designer.cs
generated
|
@ -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);
|
||||
|
|
|
@ -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<string>((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)
|
||||
|
|
Loading…
Reference in a new issue