all repos — stealth-developers @ 53c15c459294561011bea319dfc5eb4f4f4523c3

apps/bot/src/timers/index.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
let timeElapsed = 0;
let intervalId: ReturnType<typeof setInterval> | null = null;

export type TimerDeclaration = {
	name: string;
	interval: number;
	callback: () => void;
};

const timers: TimerDeclaration[] = [];

const nextFireTime: Map<string, number> = new Map();

export function addTimer(timer: TimerDeclaration): void {
	if (timers.some((t) => t.name === timer.name)) {
		console.warn(`timer with name "${timer.name}" is already registered.`);
		return;
	}

	timers.push(timer);
	nextFireTime.set(timer.name, timeElapsed + timer.interval);
}

export function removeTimer(name: string): void {
	const index = timers.findIndex((t) => t.name === name);
	if (index !== -1) {
		timers.splice(index, 1);
		nextFireTime.delete(name);
	}
}

export function startSystem(): void {
	if (intervalId !== null) {
		console.warn("timer is already running.");
		return;
	}

	intervalId = setInterval(() => {
		timeElapsed++;

		for (const timer of timers) {
			const fireAt = nextFireTime.get(timer.name) ?? 0;
			if (timeElapsed >= fireAt) {
				timer.callback();
				nextFireTime.set(timer.name, timeElapsed + timer.interval);
			}
		}
	}, 1000);
}

export function stopSystem(): void {
	if (intervalId !== null) {
		clearInterval(intervalId);
		intervalId = null;
	}
}

export function getTimeElapsed(): number {
	return timeElapsed;
}

export function resetSystem(): void {
	stopSystem();
	timers.length = 0;
	nextFireTime.clear();
	timeElapsed = 0;
}

startSystem();