Stopwatch

A simple stopwatch, with one-second resolution.

#!/usr/bin/pinafore

let

datatype StopwatchState = StoppedState Duration | RunningState Time;

toggleStopwatch : Ref +Time -> Ref StopwatchState -> Action ();
toggleStopwatch now r = do
    n <- get now;
    oldstate <- get r;
    newstate <- return $ case oldstate of
        StoppedState d -> RunningState $ addTime (negateDuration d) n;
        RunningState t -> StoppedState $ diffTime n t
        end;
    r := newstate;
    end;

showStopwatch : StopwatchState -> Time -> Text;
showStopwatch state n = case state of
    StoppedState d -> "[" <> toText d <> "]";
    RunningState t -> toText $ diffTime n t
    end;

ui : Ref +Time -> Ref StopwatchState -> UI;
ui now r = uiButton {showStopwatch %r %now} {toggleStopwatch now r};

in do
    now <- newClock $ secondsToDuration 0.001;
    r <- newMemRef;
    r := StoppedState zeroDuration;
    openWindow {"Stopwatch"} {[]} $ ui now r;
    end