diff options
Diffstat (limited to 'src/framework/GuiUnit/XwtMainLoopIntegration.cs')
-rw-r--r-- | src/framework/GuiUnit/XwtMainLoopIntegration.cs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/framework/GuiUnit/XwtMainLoopIntegration.cs b/src/framework/GuiUnit/XwtMainLoopIntegration.cs index ff6d598..485cdfb 100644 --- a/src/framework/GuiUnit/XwtMainLoopIntegration.cs +++ b/src/framework/GuiUnit/XwtMainLoopIntegration.cs @@ -76,5 +76,122 @@ namespace GuiUnit Application.GetMethod("Exit").Invoke(null, null); } } + + class ConsoleMainLoop : System.Threading.SynchronizationContext, IMainLoopIntegration + { + System.Collections.Generic.Queue<InvokerHelper> work = + new System.Collections.Generic.Queue<InvokerHelper>(); + + System.Collections.Generic.Queue<Tuple<System.Threading.SendOrPostCallback, object>> contextWork = + new System.Collections.Generic.Queue<Tuple<System.Threading.SendOrPostCallback, object>>(); + + bool endLoop; + + public void InitializeToolkit() + { + var runtime = Type.GetType("MonoDevelop.Core.Runtime, MonoDevelop.Core"); + if (runtime == null) + return; + + var property = runtime.GetProperty ("MainSynchronizationContext", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static); + if (property == null) + return; + + System.Threading.SynchronizationContext.SetSynchronizationContext(this); + property.SetValue (null, System.Threading.SynchronizationContext.Current); + } + + public void InvokeOnMainLoop (InvokerHelper helper) + { + lock (work) + { + work.Enqueue (helper); + System.Threading.Monitor.Pulse (work); + } + } + + public void RunMainLoop () + { + do + { + InvokerHelper next = null; + Tuple<System.Threading.SendOrPostCallback, object> nextContext = null; + lock (work) + { + if (work.Count > 0 && !endLoop) + next = work.Dequeue (); + else if (contextWork.Count > 0 && !endLoop) + nextContext = contextWork.Dequeue (); + else if (!endLoop) + System.Threading.Monitor.Wait (work); + } + if (next != null) + { + try + { + next.Invoke (); + } + catch (Exception ex) + { + Console.WriteLine (ex); + } + } + if (nextContext != null) + { + try + { + nextContext.Item1(nextContext.Item2); + } + catch (Exception ex) + { + Console.WriteLine(ex); + } + } + } while (!endLoop); + } + + public void Shutdown () + { + lock (work) + { + endLoop = true; + System.Threading.Monitor.Pulse (work); + } + } + + public override void Post (System.Threading.SendOrPostCallback d, object state) + { + lock (work) + { + contextWork.Enqueue (new Tuple<System.Threading.SendOrPostCallback, object>(d, state)); + System.Threading.Monitor.Pulse (work); + } + } + + public override void Send (System.Threading.SendOrPostCallback d, object state) + { + var evt = new System.Threading.ManualResetEventSlim (false); + Exception exception = null; + Post (s => + { + try + { + d.Invoke (state); + } + catch (Exception ex) + { + exception = ex; + } + finally + { + System.Threading.Thread.MemoryBarrier (); + evt.Set (); + } + }, null); + evt.Wait (); + if (exception != null) + throw exception; + } + } } |