/// <summary> /// Starts the time simulation thread /// </summary> /// <returns>A promise that represents the end of the time simulation</returns> public Promise Start() { runDeferred = Deferred.Create(); runDeferred.Promise.Finally((p) => { runDeferred = null; }); Thread t = new Thread(() => { IsRunning = true; try { current = this; while (true) { List <WorkItem> syncActions = new List <WorkItem>(); lock (syncQueue) { while (syncQueue.Count > 0) { syncActions.Add(syncQueue.Dequeue()); } } foreach (var syncAction in syncActions) { syncAction.Work(); syncAction.Deferred.Resolve(); } Tick(); AfterTick.Fire(); } } catch (StopTimeException) { IsRunning = false; runDeferred.Resolve(); } catch (Exception ex) { IsRunning = false; UnhandledException.Fire(ex); runDeferred.Reject(ex); } }) { Name = "TimeThread" }; t.Start(); return(runDeferred.Promise); }
private void Loop() { while (true) { List <WorkItem> syncActions = new List <WorkItem>(); lock (syncQueue) { while (syncQueue.Count > 0) { var workItem = syncQueue[0]; syncQueue.RemoveAt(0); syncActions.Add(workItem); } } foreach (var syncAction in syncActions) { try { CurrentlyRunningWorkItem = syncAction; Debugger?.Track(syncAction.Reason); syncAction.Work(); CurrentlyRunningWorkItem = null; } catch (StopTimeException) { throw; } catch (Exception ex) { if (syncAction.Deferred.HasExceptionListeners) { syncAction.Deferred.Reject(ex); } else { HandleWorkItemException(ex); } } if (syncAction.Deferred.IsFulfilled == false) { syncAction.Deferred.Resolve(); } } for (var i = 0; i < timeFunctions.Count; i++) { if (timeFunctions[i].Lifetime.IsExpired == false && timeFunctions[i].Governor.ShouldFire(Now)) { CurrentlyRunningFunction = timeFunctions[i]; EvaluateCurrentlyRunningFunction(); } } while (toAdd.Count > 0) { var added = toAdd[0]; toAdd.RemoveAt(0); timeFunctions.Add(added); if (added.Lifetime.IsExpired == false && added.Governor.ShouldFire(Now)) { CurrentlyRunningFunction = added; EvaluateCurrentlyRunningFunction(); } } for (var i = 0; i < toRemove.Count; i++) { timeFunctions.Remove(toRemove[i]); } toRemove.Clear(); Now += Increment; AfterTick.Fire(); } }
/// <summary> /// Starts the time simulation thread /// </summary> /// <param name="name">the name of the thread to start. This is useful when debugging.</param> /// <returns>A promise that represents the end of the time simulation</returns> public Promise Start(string name = "TimeThread") { runDeferred = Deferred.Create(); runDeferred.Promise.Finally((p) => { runDeferred = null; }); Thread t = new Thread(() => { SynchronizationContext.SetSynchronizationContext(syncContext); IsRunning = true; try { current = this; while (true) { List <WorkItem> syncActions = new List <WorkItem>(); lock (syncQueue) { while (syncQueue.Count > 0) { var workItem = syncQueue[0]; syncQueue.RemoveAt(0); syncActions.Add(workItem); } } foreach (var syncAction in syncActions) { try { syncAction.Work(); } catch (Exception ex) { if (syncAction.Deferred.HasExceptionListeners) { syncAction.Deferred.Reject(ex); } else { throw; } } if (syncAction.Deferred.IsFulfilled == false) { syncAction.Deferred.Resolve(); } } Tick(); AfterTick.Fire(); } } catch (StopTimeException) { IsRunning = false; runDeferred.Resolve(); } catch (Exception ex) { IsRunning = false; var args = new TimeExceptionArgs() { Exception = ex }; BeforeUnhandledException.Fire(args); if (args.Handled) { runDeferred.Resolve(); } else { UnhandledException.Fire(ex); runDeferred.Reject(ex); } } }) { Name = name }; t.Priority = ThreadPriority.AboveNormal; t.IsBackground = true; t.Start(); return(runDeferred.Promise); }