<> <> DIRECTORY BasicTime USING[Pulses, GetClockPulses, PulsesToSeconds], Timer USING[Seconds]; TimerImpl: MONITOR LOCKS self USING self: Handle IMPORTS BasicTime EXPORTS Timer = { <> Handle: TYPE = REF Object; Object: PUBLIC TYPE = MONITORED RECORD[ bigBangTime, previousMark: BasicTime.Pulses, secondsSinceFirstBigBang: Seconds _ 0.0 ]; Seconds: TYPE = Timer.Seconds; -- REAL-- <> Create: PUBLIC PROC RETURNS[Handle] = { startMark: BasicTime.Pulses = BasicTime.GetClockPulses[]; RETURN[NEW[Object _ [LOCK:, bigBangTime: startMark, previousMark: startMark]]]; }; Read: PUBLIC ENTRY PROC[self: Handle] RETURNS[time, deltaTime: Seconds] = { nextMark: BasicTime.Pulses _ BasicTime.GetClockPulses[]; IF BasicTime.PulsesToSeconds[nextMark] - BasicTime.PulsesToSeconds[self.bigBangTime] > 15.0*60.0 -- 15 mins THEN {self.secondsSinceFirstBigBang _ self.secondsSinceFirstBigBang + (BasicTime.PulsesToSeconds[self.previousMark]-BasicTime.PulsesToSeconds[self.bigBangTime]); self.bigBangTime _ self.previousMark}; deltaTime _ (BasicTime.PulsesToSeconds[nextMark] - BasicTime.PulsesToSeconds[self.previousMark]); time _ (BasicTime.PulsesToSeconds[nextMark]-BasicTime.PulsesToSeconds[self.bigBangTime]) + self.secondsSinceFirstBigBang; self.previousMark _ nextMark; }; Reset: PUBLIC ENTRY PROC[self: Handle] = { startMark: BasicTime.Pulses = BasicTime.GetClockPulses[]; self.bigBangTime _ self.previousMark _ startMark; self.secondsSinceFirstBigBang _ 0.0; }; }.