Esempio n. 1
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);
        }