Skip to content

Instantly share code, notes, and snippets.

@furf
Last active July 9, 2020 16:20
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save furf/ed6006c195d1dd69a824129f9946ddb3 to your computer and use it in GitHub Desktop.
A stopwatch-like timer
const Events = new Map();
function startEvent() {
return {
start: Date.now(),
end: null,
};
}
function endEvent(event) {
if (!event || event.end !== null) {
throw new Error('Unable to end event.');
}
return {
...event,
end: Date.now(),
};
}
class Timer {
static IDLE = Symbol('IDLE');
static ACTIVE = Symbol('ACTIVE');
static PAUSED = Symbol('PAUSED');
static STOPPED = Symbol('STOPPED');
/**
*
*/
get state() {
const events = Events.get(this);
if (events.length === 0) {
return Timer.IDLE;
}
const event = events[events.length - 1];
if (event === null) {
return Timer.STOPPED;
}
if (event.end === null) {
return Timer.ACTIVE;
}
return Timer.PAUSED;
}
/**
*
*/
get active() {
return this.state === Timer.ACTIVE;
}
/**
*
*/
get paused() {
return (
this.state === Timer.IDLE ||
this.state === Timer.PAUSED ||
this.state === Timer.STOPPED
);
}
/**
*
*/
get stopped() {
return this.state === Timer.STOPPED;
}
/**
*
*/
get time() {
const events = Events.get(this);
const total = events.reduce((subtotal, event) => {
if (event === null) return subtotal;
const end = event.end === null ? Date.now() : event.end;
const duration = end - event.start;
return subtotal + duration;
}, 0);
return total;
}
/**
*
*/
constructor() {
Events.set(this, []);
}
/**
*
*/
start() {
if (this.stopped || this.state === Timer.ACTIVE) return;
const events = Events.get(this);
const event = startEvent();
Events.set(this, [...events, event]);
}
/**
*
*/
pause() {
if (this.paused) return;
const events = Events.get(this);
const event = endEvent(events[events.length - 1]);
Events.set(this, [...events.slice(0, -1), event]);
}
/**
*
*/
stop() {
if (this.stopped) return;
if (!this.paused) {
this.pause();
}
const events = Events.get(this);
const event = null;
Events.set(this, [...events, event]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment