using System.Collections.Generic;
namespace Cryville.Crtr {
///
/// 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);
}
}