private void StartExecution(ScriptJobBase job) { if (Prefs.EnableGameScripts == false) return; _executionQueue.Enqueue(job); if (_executionQueue.Count == 1) // Other scripts may be hung. Scripts are executed in order. ProcessExecutionQueue(); }
internal T Invoke<T>(Func<T> func) { ScriptJobBase job = _executionQueue.Peek(); job.InvokedOperation = func; job.DispatcherSignal.Set(); job.WorkerSignal.WaitOne(); return (T)job.InvokeResult; }
private void ProcessExecutionQueue() { do { ScriptJobBase job = _executionQueue.Peek(); var scriptjob = job as ScriptJob; if (scriptjob != null) { Program.GameMess.GameDebug(scriptjob.Source.GetCode()); } // Because some scripts have to be suspended during asynchronous operations (e.g. shuffle, reveal or random), // their evaluation is done on another thread. // The process still looks synchronous (no concurrency is allowed when manipulating the game model), // which is why a ManualResetEvent is used to synchronise the work of both threads if (job.Suspended) { job.Suspended = false; job.WorkerSignal.Set(); } else { job.DispatcherSignal = new AutoResetEvent(false); job.WorkerSignal = new AutoResetEvent(false); ThreadPool.QueueUserWorkItem(Execute, job); } job.DispatcherSignal.WaitOne(); while (job.InvokedOperation != null) { using (new Mute(job.Muted)) job.InvokeResult = job.InvokedOperation.DynamicInvoke(); job.InvokedOperation = null; job.WorkerSignal.Set(); job.DispatcherSignal.WaitOne(); } if (job.Result != null && !String.IsNullOrWhiteSpace(job.Result.Error)) { Program.GameMess.Warning("{0}", job.Result.Error.Trim()); } if (job.Suspended) { return; } job.DispatcherSignal.Dispose(); job.WorkerSignal.Dispose(); _executionQueue.Dequeue(); if (job.Continuation != null) { job.Continuation(job.Result); } } while (_executionQueue.Count > 0); }
internal void Invoke(Action action) { ScriptJobBase job = CurrentJob; job.InvokedOperation = action; //job.invokedOperation = () => // { // action(); // return null; // }; job.DispatcherSignal.Set(); job.WorkerSignal.WaitOne(); }
public void Mute(bool muted) { ScriptJobBase job = _engine.CurrentJob; _engine.CurrentJob.Muted = muted ? job.id : 0; }