Path: blob/master/src/library/utils/scheduling.ts
1784 views
/* eslint-disable @typescript-eslint/ban-types */1import { system, world } from "@minecraft/server";23let ready = false;4world.afterEvents.worldLoad.subscribe(() => (ready = true));56const tickTimeoutMap = new Map();7const tickIntervalMap = new Map();8let tickTimeoutID = 0,9tickIntervalID = 0;1011/**12* Delay executing a function13* @typedef14* @param {string | Function} handler Function you want to execute15* @param {number} [timeout] Time delay in ticks. 20 ticks is 1 second16* @param {any[]} args Function parameters for your handler17* @returns {number}18*/19function setTickTimeout(handler: string | Function, timeout = 1, ...args: unknown[]): number {20const tickTimeout = { callback: handler, tick: timeout, args };21tickTimeoutID++;22tickTimeoutMap.set(tickTimeoutID, tickTimeout);23return tickTimeoutID;24}25/**26* Delay executing a function, REPEATEDLY27* @typedef28* @param {string | Function} handler Function you want to execute29* @param {number} [timeout] Time delay in ticks. 20 ticks is 1 second30* @param {any[]} args Function parameters for your handler31* @returns {number}32*/33function setTickInterval(handler: string | Function, timeout = 1, ...args: unknown[]): number {34const tickInterval = { callback: handler, tick: timeout, args };35tickIntervalID++;36tickIntervalMap.set(tickIntervalID, tickInterval);37return tickIntervalID;38}39/**40* Delete a clearTickTimeout41* @typedef42* @param {number} handle Index you want to delete43*/44function clearTickTimeout(handle: number): void {45tickTimeoutMap.delete(handle);46}47/**48* Delete a clearTickInterval49* @typedef50* @param {number} handle Index you want to delete51*/52function clearTickInterval(handle: number): void {53tickIntervalMap.delete(handle);54}5556let totalTick = 0;57system.runInterval(() => {58totalTick++;59for (const [ID, tickTimeout] of tickTimeoutMap) {60tickTimeout.tick--;61if (tickTimeout.tick <= 0) {62tickTimeout.callback(...tickTimeout.args);63tickTimeoutMap.delete(ID);64}65}66for (const [, tickInterval] of tickIntervalMap) {67if (totalTick % tickInterval.tick === 0) tickInterval.callback(...tickInterval.args);68}69});7071function sleep(ticks: number) {72return new Promise<void>((resolve) => setTickTimeout(resolve, ticks));73}7475function whenReady<T>(callback: () => T) {76if (ready) {77const result = callback();78return Promise.resolve(result);79}8081return new Promise<T>((resolve) => {82const tickInterval = setTickInterval(() => {83if (!ready) return;84resolve(callback());85clearTickInterval(tickInterval);86});87});88}8990function everyCall(times: number) {91let count = 0;92return function (callback: () => void) {93if (count-- > 0) return;94count = times;95callback();96};97}9899function shutdownTimers() {100tickTimeoutMap.clear();101tickIntervalMap.clear();102}103104class Timer {105private time = Date.now();106private isActive = false;107108start() {109if (!this.isActive) {110this.time = Date.now();111this.isActive = true;112}113}114115getTime() {116if (this.isActive) {117return Date.now() - this.time;118}119}120121end() {122if (this.isActive) {123this.isActive = false;124return Date.now() - this.time;125}126}127}128129/**130* Creates a timer and starts it.131*/132function startTime() {133const timer = new Timer();134timer.start();135return timer;136}137138export { setTickTimeout, setTickInterval, clearTickTimeout, clearTickInterval, shutdownTimers, sleep, startTime, whenReady, Timer, everyCall };139140141