Skip to content

Commit 585971f

Browse files
committed
1 parent bf35f0b commit 585971f

3 files changed

Lines changed: 366 additions & 3 deletions

File tree

scripts/timers/timers-test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { setTimeout, setImmediate, setInterval, clearImmediate, clearInterval, clearTimeout } from "./timers.js";
2+
import { world } from "mojang-minecraft";
3+
function stdout() {
4+
var data = [];
5+
for (var _i = 0; _i < arguments.length; _i++) {
6+
data[_i] = arguments[_i];
7+
}
8+
return world.getDimension("overworld").runCommand("say \u00A7r" + data.join(" "));
9+
}
10+
;
11+
function stderr() {
12+
var data = [];
13+
for (var _i = 0; _i < arguments.length; _i++) {
14+
data[_i] = arguments[_i];
15+
}
16+
return world.getDimension("overworld").runCommand("say \u00A7c" + data.join(" "));
17+
}
18+
;
19+
// timeout test
20+
setTimeout(function (arg, arg1) {
21+
stdout("arg", arg, "arg1", arg1);
22+
}, 1000, "hello", "world", 1);
23+
stdout("setTimeout passed");
24+
// cleartimeout test
25+
var timeout2 = setTimeout(function () {
26+
stderr("clearTimeout failed");
27+
}, 1000);
28+
clearTimeout(timeout2);
29+
stdout("clearTimeout passed");
30+
// setinterval test
31+
var interval = setInterval(function (arg, arg1) {
32+
stdout("arg", arg, "arg1", arg1);
33+
}, 1000, "set", "interval", 1);
34+
stdout("setTimeout passed");
35+
// clearinterval test
36+
interval._onTimeout = function () {
37+
stderr("clearInterval failed");
38+
};
39+
clearInterval(interval);
40+
stdout("clearInterval passed");
41+
// setimmediate test
42+
setImmediate(function () {
43+
stdout("setImmediate passed");
44+
});
45+
// clearimmediate test
46+
var immediate = setImmediate(function () {
47+
stderr("setImmediate failed");
48+
});
49+
clearImmediate(immediate);
50+
stdout("clearImmediate passed");

scripts/timers/timers.js

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
var __extends = (this && this.__extends) || (function () {
2+
var extendStatics = function (d, b) {
3+
extendStatics = Object.setPrototypeOf ||
4+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
5+
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
6+
return extendStatics(d, b);
7+
};
8+
return function (d, b) {
9+
if (typeof b !== "function" && b !== null)
10+
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
11+
extendStatics(d, b);
12+
function __() { this.constructor = d; }
13+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
14+
};
15+
})();
16+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
17+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
18+
return new (P || (P = Promise))(function (resolve, reject) {
19+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
20+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
21+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
22+
step((generator = generator.apply(thisArg, _arguments || [])).next());
23+
});
24+
};
25+
var __generator = (this && this.__generator) || function (thisArg, body) {
26+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
27+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
28+
function verb(n) { return function (v) { return step([n, v]); }; }
29+
function step(op) {
30+
if (f) throw new TypeError("Generator is already executing.");
31+
while (_) try {
32+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
33+
if (y = 0, t) op = [op[0] & 2, t.value];
34+
switch (op[0]) {
35+
case 0: case 1: t = op; break;
36+
case 4: _.label++; return { value: op[1], done: false };
37+
case 5: _.label++; y = op[1]; op = [0]; continue;
38+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
39+
default:
40+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
41+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
42+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
43+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
44+
if (t[2]) _.ops.pop();
45+
_.trys.pop(); continue;
46+
}
47+
op = body.call(thisArg, _);
48+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
49+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
50+
}
51+
};
52+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
53+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
54+
if (ar || !(i in from)) {
55+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
56+
ar[i] = from[i];
57+
}
58+
}
59+
return to.concat(ar || Array.prototype.slice.call(from));
60+
};
61+
/**
62+
* The `timer` module exposes a global API for scheduling functions to
63+
* be called at some future period of time.
64+
*
65+
* The timer functions within this script implement a similar API as the timers API
66+
* provided by Web Browsers and Node.js but use a different internal implementation that is
67+
* built for QuickJS, specifically for Minecraft Bedrock Edition script APIs (experimental).
68+
*/
69+
/**
70+
* Internal timer class that can be used to reference
71+
* the set Timeout or Interval object.
72+
*/
73+
var Timer = /** @class */ (function () {
74+
function Timer(idleTimeout, idleStart, onTimeout, repeat, destroyed) {
75+
var args = [];
76+
for (var _i = 5; _i < arguments.length; _i++) {
77+
args[_i - 5] = arguments[_i];
78+
}
79+
var _this = this;
80+
this._idleTimeout = idleTimeout;
81+
this._idleStart = idleStart;
82+
this._onTimeout = onTimeout;
83+
this._repeat = repeat;
84+
this._destroyed = destroyed;
85+
(function () { return __awaiter(_this, void 0, void 0, function () {
86+
var executionTime, executionTime;
87+
return __generator(this, function (_a) {
88+
switch (_a.label) {
89+
case 0:
90+
if (!(repeat === true)) return [3 /*break*/, 4];
91+
_a.label = 1;
92+
case 1:
93+
if (!true) return [3 /*break*/, 3];
94+
return [4 /*yield*/, this._destroyed];
95+
case 2:
96+
if ((_a.sent()) === true)
97+
return [2 /*return*/];
98+
executionTime = idleStart + idleTimeout;
99+
if (new Date().getTime() >= executionTime) {
100+
this._onTimeout.apply(this, args);
101+
this._idleStart = idleStart = new Date().getTime();
102+
}
103+
;
104+
return [3 /*break*/, 1];
105+
case 3:
106+
;
107+
return [3 /*break*/, 8];
108+
case 4:
109+
executionTime = idleStart + idleTimeout;
110+
_a.label = 5;
111+
case 5:
112+
if (!(new Date().getTime() < executionTime)) return [3 /*break*/, 7];
113+
return [4 /*yield*/, this._destroyed];
114+
case 6:
115+
if ((_a.sent()) === true)
116+
return [2 /*return*/];
117+
return [3 /*break*/, 5];
118+
case 7:
119+
;
120+
this._onTimeout.apply(this, args);
121+
_a.label = 8;
122+
case 8:
123+
;
124+
return [2 /*return*/];
125+
}
126+
});
127+
}); })();
128+
}
129+
;
130+
return Timer;
131+
}());
132+
;
133+
var Timeout = /** @class */ (function (_super) {
134+
__extends(Timeout, _super);
135+
function Timeout(idleTimeout, idleStart, onTimeout, repeat, destroyed) {
136+
var args = [];
137+
for (var _i = 5; _i < arguments.length; _i++) {
138+
args[_i - 5] = arguments[_i];
139+
}
140+
var _this = _super.apply(this, __spreadArray([idleTimeout, idleStart, onTimeout, repeat, destroyed], args, false)) || this;
141+
_this._idleTimeout = idleTimeout;
142+
_this._idleStart = idleStart;
143+
_this._onTimeout = onTimeout;
144+
_this._repeat = repeat;
145+
_this._destroyed = destroyed;
146+
return _this;
147+
}
148+
;
149+
return Timeout;
150+
}(Timer));
151+
;
152+
/**
153+
* Internal timer class that can be used to reference
154+
* the set Immediate object.
155+
*/
156+
var Immediate = /** @class */ (function () {
157+
function Immediate(onImmediate) {
158+
var args = [];
159+
for (var _i = 1; _i < arguments.length; _i++) {
160+
args[_i - 1] = arguments[_i];
161+
}
162+
var _this = this;
163+
this._destroyed = false;
164+
this._onImmediate = onImmediate;
165+
this._argv = args;
166+
(function () { return __awaiter(_this, void 0, void 0, function () {
167+
return __generator(this, function (_a) {
168+
switch (_a.label) {
169+
case 0: return [4 /*yield*/, this._destroyed];
170+
case 1:
171+
if ((_a.sent()) === true)
172+
return [2 /*return*/];
173+
return [4 /*yield*/, this._onImmediate.apply(this, args)];
174+
case 2:
175+
_a.sent();
176+
return [2 /*return*/];
177+
}
178+
});
179+
}); })();
180+
}
181+
;
182+
return Immediate;
183+
}());
184+
;
185+
function Validation(parameter, instance) {
186+
if (parameter instanceof instance)
187+
return;
188+
throw TypeError("Native type conversion failed");
189+
}
190+
;
191+
/**
192+
* @param callback a function to execute as its first argument
193+
* @param ms the millisecond delay defined as a number as the second argument.
194+
* @param args Additional arguments may also be included and these will be passed on to the function.
195+
*
196+
* @example
197+
* ```js
198+
* function myFunc(arg) {
199+
* console.log(`arg was => ${arg}`);
200+
* }
201+
*
202+
* setTimeout(myFunc, 1500, 'funky');
203+
* ```
204+
*/
205+
// @ts-ignore
206+
function setTimeout(callback, ms) {
207+
var args = [];
208+
for (var _i = 2; _i < arguments.length; _i++) {
209+
args[_i - 2] = arguments[_i];
210+
}
211+
Validation(callback, Function);
212+
var idleTime = typeof ms === "number" ? ms : 1;
213+
var startTime = new Date().getTime();
214+
// @ts-ignore
215+
return new (Timeout.bind.apply(Timeout, __spreadArray([void 0, idleTime, startTime, callback, false, false], args, false)))();
216+
}
217+
;
218+
/**
219+
* By passing said object into the respective clear function,
220+
* execution of that object will be halted completely.
221+
* @param timeoutId Timeout object returned by `setTimeout()`
222+
*/
223+
// @ts-ignore
224+
function clearTimeout(timeoutId) {
225+
if (!(timeoutId instanceof Timeout))
226+
return;
227+
timeoutId._destroyed = true;
228+
timeoutId._onTimeout = function () { };
229+
}
230+
;
231+
/**
232+
* @param callback Takes a function argument that will run an infinite number of times
233+
* @param ms A given millisecond delay as the second argument
234+
* @param args Just like `setTimeout()`, additional arguments can be added beyond the delay,
235+
* and these will be passed on to the function call.
236+
* @example
237+
* ```js
238+
* function intervalFunc() {
239+
* console.log('Cant stop me now!');
240+
* }
241+
*
242+
* setInterval(intervalFunc, 1500);
243+
* ```
244+
*/
245+
// @ts-ignore
246+
function setInterval(callback, ms) {
247+
var args = [];
248+
for (var _i = 2; _i < arguments.length; _i++) {
249+
args[_i - 2] = arguments[_i];
250+
}
251+
Validation(callback, Function);
252+
var idleTime = typeof ms === "number" ? ms : 1;
253+
var startTime = new Date().getTime();
254+
// @ts-ignore
255+
return new (Timer.bind.apply(Timer, __spreadArray([void 0, idleTime, startTime, callback, true, false], args, false)))();
256+
}
257+
;
258+
/**
259+
* By passing said object into the respective clear function,
260+
* execution of that object will be halted completely.
261+
* @param intervalId Interval object returned by `setInterval()`
262+
*/
263+
// @ts-ignore
264+
function clearInterval(intervalId) {
265+
if (!(intervalId instanceof Timer))
266+
return;
267+
intervalId._destroyed = true;
268+
intervalId._onTimeout = function () { };
269+
}
270+
;
271+
/**
272+
* @param callback The function to execute
273+
* @param args Any subsequent arguments will be passed to the function when it is executed.
274+
*
275+
* @example
276+
* ```js
277+
* console.log('before immediate');
278+
*
279+
* setImmediate((arg) => {
280+
* console.log(`executing immediate: ${arg}`);
281+
* }, 'so immediate');
282+
*
283+
* console.log('after immediate');
284+
* ```
285+
*/
286+
// @ts-ignore
287+
function setImmediate(callback) {
288+
var args = [];
289+
for (var _i = 1; _i < arguments.length; _i++) {
290+
args[_i - 1] = arguments[_i];
291+
}
292+
Validation(callback, Function);
293+
// @ts-ignore
294+
return new (Immediate.bind.apply(Immediate, __spreadArray([void 0, callback], args, false)))();
295+
}
296+
;
297+
/**
298+
* By passing said object into the respective clear function,
299+
* execution of that object will be halted completely.
300+
* @param immediateId Immediate object returned by `setImmediate()`
301+
*/
302+
// @ts-ignore
303+
function clearImmediate(immediateId) {
304+
if (!(immediateId instanceof Immediate))
305+
return;
306+
immediateId._destroyed = true;
307+
immediateId._onImmediate = function () { };
308+
}
309+
;
310+
/**
311+
* Timers function are exported so developers
312+
* can choose which set of functions they want to
313+
* withdraw from the `timers` module.
314+
*/
315+
export { setTimeout, clearTimeout, setInterval, clearInterval, setImmediate, clearImmediate };

scripts/timers/timers.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,9 @@ class Timer {
3636
};
3737
};
3838
} else {
39-
if (await this._destroyed === true) return;
40-
4139
const executionTime = idleStart + idleTimeout;
4240
while (new Date().getTime() < executionTime) {
43-
void 0;
41+
if (await this._destroyed === true) return;
4442
};
4543

4644
this._onTimeout(...args);

0 commit comments

Comments
 (0)