Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sisilicon
GitHub Repository: sisilicon/worldedit-be
Path: blob/master/src/library/utils/scheduling.ts
1784 views
1
/* eslint-disable @typescript-eslint/ban-types */
2
import { system, world } from "@minecraft/server";
3
4
let ready = false;
5
world.afterEvents.worldLoad.subscribe(() => (ready = true));
6
7
const tickTimeoutMap = new Map();
8
const tickIntervalMap = new Map();
9
let tickTimeoutID = 0,
10
tickIntervalID = 0;
11
12
/**
13
* Delay executing a function
14
* @typedef
15
* @param {string | Function} handler Function you want to execute
16
* @param {number} [timeout] Time delay in ticks. 20 ticks is 1 second
17
* @param {any[]} args Function parameters for your handler
18
* @returns {number}
19
*/
20
function setTickTimeout(handler: string | Function, timeout = 1, ...args: unknown[]): number {
21
const tickTimeout = { callback: handler, tick: timeout, args };
22
tickTimeoutID++;
23
tickTimeoutMap.set(tickTimeoutID, tickTimeout);
24
return tickTimeoutID;
25
}
26
/**
27
* Delay executing a function, REPEATEDLY
28
* @typedef
29
* @param {string | Function} handler Function you want to execute
30
* @param {number} [timeout] Time delay in ticks. 20 ticks is 1 second
31
* @param {any[]} args Function parameters for your handler
32
* @returns {number}
33
*/
34
function setTickInterval(handler: string | Function, timeout = 1, ...args: unknown[]): number {
35
const tickInterval = { callback: handler, tick: timeout, args };
36
tickIntervalID++;
37
tickIntervalMap.set(tickIntervalID, tickInterval);
38
return tickIntervalID;
39
}
40
/**
41
* Delete a clearTickTimeout
42
* @typedef
43
* @param {number} handle Index you want to delete
44
*/
45
function clearTickTimeout(handle: number): void {
46
tickTimeoutMap.delete(handle);
47
}
48
/**
49
* Delete a clearTickInterval
50
* @typedef
51
* @param {number} handle Index you want to delete
52
*/
53
function clearTickInterval(handle: number): void {
54
tickIntervalMap.delete(handle);
55
}
56
57
let totalTick = 0;
58
system.runInterval(() => {
59
totalTick++;
60
for (const [ID, tickTimeout] of tickTimeoutMap) {
61
tickTimeout.tick--;
62
if (tickTimeout.tick <= 0) {
63
tickTimeout.callback(...tickTimeout.args);
64
tickTimeoutMap.delete(ID);
65
}
66
}
67
for (const [, tickInterval] of tickIntervalMap) {
68
if (totalTick % tickInterval.tick === 0) tickInterval.callback(...tickInterval.args);
69
}
70
});
71
72
function sleep(ticks: number) {
73
return new Promise<void>((resolve) => setTickTimeout(resolve, ticks));
74
}
75
76
function whenReady<T>(callback: () => T) {
77
if (ready) {
78
const result = callback();
79
return Promise.resolve(result);
80
}
81
82
return new Promise<T>((resolve) => {
83
const tickInterval = setTickInterval(() => {
84
if (!ready) return;
85
resolve(callback());
86
clearTickInterval(tickInterval);
87
});
88
});
89
}
90
91
function everyCall(times: number) {
92
let count = 0;
93
return function (callback: () => void) {
94
if (count-- > 0) return;
95
count = times;
96
callback();
97
};
98
}
99
100
function shutdownTimers() {
101
tickTimeoutMap.clear();
102
tickIntervalMap.clear();
103
}
104
105
class Timer {
106
private time = Date.now();
107
private isActive = false;
108
109
start() {
110
if (!this.isActive) {
111
this.time = Date.now();
112
this.isActive = true;
113
}
114
}
115
116
getTime() {
117
if (this.isActive) {
118
return Date.now() - this.time;
119
}
120
}
121
122
end() {
123
if (this.isActive) {
124
this.isActive = false;
125
return Date.now() - this.time;
126
}
127
}
128
}
129
130
/**
131
* Creates a timer and starts it.
132
*/
133
function startTime() {
134
const timer = new Timer();
135
timer.start();
136
return timer;
137
}
138
139
export { setTickTimeout, setTickInterval, clearTickTimeout, clearTickInterval, shutdownTimers, sleep, startTime, whenReady, Timer, everyCall };
140
141