@toreda/time
Version:
Simple, small footprint library for common time operations and converting between units of time.
166 lines (165 loc) • 5.6 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TimerActive = void 0;
const group_1 = require("./callback/group");
const mutable_1 = require("../mutable");
const make_1 = require("../time/make");
const now_1 = require("../time/now");
/**
* Active timer driven by external ticker calls to `onUpdate`.
*
* @category Timers
*/
class TimerActive {
constructor(options) {
this.lastIntervalEnd = (0, mutable_1.mutable)(0);
this.running = false;
this.limitDuration = typeof (options === null || options === void 0 ? void 0 : options.limitDuration) === 'boolean' ? options.limitDuration : false;
this.timeStart = (0, make_1.timeMake)('s', 0);
this.timeStop = (0, make_1.timeMake)('s', 0);
const timeLimit = typeof (options === null || options === void 0 ? void 0 : options.timeLimit) === 'number' ? options.timeLimit : 0;
this.timeLimit = (0, make_1.timeMake)('s', timeLimit);
this.paused = false;
this.listeners = {
start: new group_1.TimerCallbackGroup('start'),
stop: new group_1.TimerCallbackGroup('stop'),
pause: new group_1.TimerCallbackGroup('pause'),
unpause: new group_1.TimerCallbackGroup('unpause'),
done: new group_1.TimerCallbackGroup('done'),
restart: new group_1.TimerCallbackGroup('restart'),
reset: new group_1.TimerCallbackGroup('reset')
};
this.start = this.start.bind(this);
this.stop = this.stop.bind(this);
this.onUpdate = this.onUpdate.bind(this);
}
getListenerGroup(id) {
const group = this.listeners[id];
if (!group) {
return null;
}
return group;
}
on(id, fn) {
if (typeof fn !== 'function') {
return false;
}
const group = this.getListenerGroup(id);
if (!group) {
return false;
}
return group.always(fn);
}
once(id, fn) {
if (typeof fn !== 'function') {
return false;
}
const group = this.getListenerGroup(id);
if (!group) {
return false;
}
return group.once(fn);
}
setTimeLimit(value) {
if (value === undefined || value === null) {
return false;
}
if (typeof value === 'number') {
this.timeLimit.set(value);
return true;
}
if (value.type === 'Time') {
this.timeLimit.set(value.asSeconds());
return true;
}
return false;
}
unpause() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.running || !this.paused) {
return false;
}
yield this.executeCallbacks('unpause');
this.paused = false;
return true;
});
}
pause() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.running || this.paused) {
return false;
}
yield this.executeCallbacks('pause');
this.paused = true;
return true;
});
}
/**
* Start the timer.
*/
start() {
return __awaiter(this, void 0, void 0, function* () {
if (this.running) {
return false;
}
this.timeStart.setNow();
yield this.executeCallbacks('start');
this.running = true;
return true;
});
}
done() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.running) {
return false;
}
yield this.executeCallbacks('done');
return this.stop();
});
}
stop() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.running) {
return false;
}
this.timeStop.setNow();
yield this.executeCallbacks('stop');
this.running = false;
return true;
});
}
executeCallbacks(eventId) {
return __awaiter(this, void 0, void 0, function* () {
const group = this.listeners[eventId];
if (!group) {
return;
}
const elapsed = this.timeStart.since((0, now_1.timeNow)());
const duration = elapsed ? elapsed() : 0;
yield group.executeAll(duration);
});
}
onUpdate() {
if (!this.running) {
return;
}
const now = (0, now_1.timeNow)();
if (this.limitDuration) {
const duration = this.timeStart.since(now);
if (duration && duration() >= this.timeLimit()) {
this.done();
return;
}
}
}
}
exports.TimerActive = TimerActive;