using System.Collections.Generic; namespace Cryville.Crtr.Event { /// /// A time-forward handler of a sequence of events. /// /// The event type. public abstract class StateBase { /// /// The current time of the state in seconds. /// public double Time { get; protected set; } /// /// The index of the event to be handled next. /// public int EventId { get; protected set; } /// /// The event count. /// public int EventCount { get { return Events.Count; } } /// /// The event list. /// protected readonly List Events; bool breakflag = false; /// /// Creates an instance of the class. /// /// The event list. public StateBase(List evs) { Events = evs; EventId = 0; Time = 0; } /// /// Creates a copy of the current state. /// /// A copy of the current state. /// /// is shared across copies. /// public virtual StateBase Clone() { return (StateBase)MemberwiseClone(); } /// /// Copies the state to another existing state. /// /// The state to be overridden. public virtual void CopyTo(StateBase dest) { dest.Time = Time; dest.EventId = EventId; dest.breakflag = breakflag; } /// /// Interrupts the forward process. /// public virtual void Break() { breakflag = true; } /// /// Walks through all the remaining events. /// public void Forward() { ForwardToTime(double.PositiveInfinity); } /// /// Forwards to the next event. /// public void ForwardOnce() { ForwardOnceToTime(double.PositiveInfinity); } /// /// Forwards the time by the specified span and walks through all the encountered events. /// /// The span in seconds. public void ForwardByTime(double time) { ForwardToTime(Time + time); } /// /// Forwards the time by the specified span but walks through at most one event. /// /// The span in seconds. public void ForwardOnceByTime(double time) { ForwardOnceToTime(Time + time); } /// /// Forwards the time to the specified time and walks through all the encountered events. /// /// The time in seconds. public void ForwardToTime(double toTime) { breakflag = false; ForwardOnceToTime(Time); while (Time < toTime) { ForwardOnceToTime(toTime); if (breakflag) break; } } /// /// Forwards the time by the specified span and walks through all the encountered events, with a specified step. /// /// The span in seconds. /// The step in seconds. public void ForwardStepByTime(double time, double step) { ForwardStepToTime(Time + time, step); } /// /// Forwards the time to the specified time and walks through all the encountered events, with a specified step. /// /// The time in seconds. /// The step in seconds. public void ForwardStepToTime(double toTime, double step) { breakflag = false; ForwardOnceToTime(Time); while (Time < toTime) { double next = Time + step; ForwardOnceToTime(next < toTime ? next : toTime); if (breakflag) break; } } /// /// Forwards the time to the specified time but walks through at most one event. /// /// The time in seconds. public abstract void ForwardOnceToTime(double toTime); } }