Example #1
0
 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();
 }
Example #2
0
 internal T Invoke<T>(Func<T> func)
 {
     ScriptJobBase job = _executionQueue.Peek();
     job.InvokedOperation = func;
     job.DispatcherSignal.Set();
     job.WorkerSignal.WaitOne();
     return (T)job.InvokeResult;
 }
Example #3
0
        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);
        }
Example #4
0
 internal void Invoke(Action action)
 {
     ScriptJobBase job = CurrentJob;
     job.InvokedOperation = action;
     //job.invokedOperation = () =>
     //                           {
     //                               action();
     //                               return null;
     //                           };
     job.DispatcherSignal.Set();
     job.WorkerSignal.WaitOne();
 }
Example #5
0
        public void Mute(bool muted)
        {
            ScriptJobBase job = _engine.CurrentJob;

            _engine.CurrentJob.Muted = muted ? job.id : 0;
        }