/// <summary> /// Runs event loop till either current time is greater than passed endTime or there are no more scheduled events. /// </summary> /// <param name="endTime">Simulation time indicating when to stop simulation.</param> public static void Run() { whenStarted = DateTime.Now; const string progressText = "Simulating."; ProgressLogger.Starting(progressText); ProgressLogger.Progress(); lastShown = DateTime.Now; while(events.Count>0 && currentTime <= simulationTime) { //show progress if (lastShown + showingDelay < DateTime.Now) { ProgressLogger.Progress(); lastShown = DateTime.Now; } ++loopNumber; //next event; TimerEntryImplementation entry = events.DeleteMin(); currentTime = entry.Time; entry.Method(entry); } if (events.Count == 0) { Console.WriteLine("No more events to handle."); } if (currentTime > simulationTime) { Console.WriteLine("Simulation came to its end time."); } ProgressLogger.Finished(progressText); }
/// <summary> /// Cancels scheduled event. /// </summary> /// <param name="entry">Object returned from Schedule method as event ID.</param> public static void Cancel(TimerEntry entry) { //entries after end of simulation if (entry.Time > simulationTime) return; TimerEntryImplementation implementation = (TimerEntryImplementation)entry; TimerEntryImplementation deleted = events.Delete(implementation.Handle); Debug.Assert(implementation == deleted); }
//INTERFACE /// <summary> /// Schedules an event to be fired at givent time /// </summary> /// <param name="time">Double type is used as time representation (in seconds). Pass simulation time (not delay).</param> /// <param name="method">Method to called at given time.</param> /// <param name="userData">User data that can be obtained from Timer Event when the method is called.</param> /// <returns>TimerEntry class is used as both timer ID and container having all data associated with a single event. The same objest is going to be passed to method on event.</returns> public static TimerEntry Schedule(double time, TimerEntryDelegate method, object userData) { Debug.Assert(time >= currentTime); TimerEntryImplementation entry = new TimerEntryImplementation(time, userData, method); //ignore entries that will take place after end of simulation. if (time <= simulationTime) { bool added = events.Add(ref entry.Handle, entry); Debug.Assert(added); } return entry; }