60 lines
2.2 KiB
TypeScript
60 lines
2.2 KiB
TypeScript
|
|
export type TimeMode = TimePaused | TimeRealTime;
|
|
|
|
// When the simulation is paused, we only need to know the current simulated time.
|
|
export type TimePaused = {
|
|
kind: "paused",
|
|
simtime: number, // the current simulated time
|
|
}
|
|
|
|
// When the simulation is running in real time, we need to know the time when the simulation was set to real time (both in simulated and wall-clock time), and the time scale. This allows us to compute the simulated time of every future event.
|
|
// Such a 'future event' may be:
|
|
// - raising an input event
|
|
// - changing of the time scale parameter
|
|
// - pausing the simulation
|
|
export type TimeRealTime = {
|
|
kind: "realtime",
|
|
since: {
|
|
simtime: number, // the simulated time at which the time was set to realtime
|
|
wallclktime: number, // the wall-clock time at which the time was set to realtime
|
|
}
|
|
scale: number, // time scale relative to wall-clock time
|
|
}
|
|
|
|
// given a wall-clock time, how does it translate to simtime?
|
|
export function getSimTime(currentMode: TimeMode, wallclktime: number): number {
|
|
if (currentMode.kind === "paused") {
|
|
return currentMode.simtime;
|
|
}
|
|
else {
|
|
const elapsedWallclk = wallclktime - currentMode.since.wallclktime;
|
|
return currentMode.since.simtime + currentMode.scale * elapsedWallclk;
|
|
}
|
|
}
|
|
|
|
// given a simulated real time clock, how long will it take in wall-clock time duration until 'simtime' is the current time?
|
|
export function getWallClkDelay(realtime: TimeRealTime, simtime: number, wallclktime: number): number {
|
|
const currentSimTime = getSimTime(realtime, wallclktime);
|
|
const simtimeDelay = simtime - currentSimTime;
|
|
return Math.max(0, simtimeDelay / realtime.scale);
|
|
}
|
|
|
|
// given a current simulated clock (paused or real time), switch to real time with given time scale
|
|
export function setRealtime(currentMode: TimeMode, scale: number, wallclktime: number): TimeRealTime {
|
|
return {
|
|
kind: "realtime",
|
|
scale,
|
|
since: {
|
|
simtime: getSimTime(currentMode, wallclktime),
|
|
wallclktime,
|
|
},
|
|
};
|
|
}
|
|
|
|
// given a current simulated clock (paused or real time), switch to paused
|
|
export function setPaused(currentMode: TimeMode, wallclktime: number): TimePaused {
|
|
return {
|
|
kind: "paused",
|
|
simtime: getSimTime(currentMode, wallclktime),
|
|
};
|
|
}
|