yoni-mcscripts-lib
Version:
为 Minecraft Script API 中的部分接口创建了 wrapper,并提供简单的事件管理器和任务管理器,另附有一些便于代码编写的一些小工具。
152 lines (151 loc) • 5.74 kB
JavaScript
// @ts-nocheck
import { debug } from "../config.js";
import { EventTypes, EventRegisterListener, getIdentifierInfo } from "./Types.js";
import { logger } from "./logger.js";
/**
* 事件监听管理。
*
* 不建议移除事件,由于移除事件的机制为设空回调,导致移除事件并不是真正的移除,大量移除事件导致事件遗留,可能影响性能。
*
* ~~可能会在以后优化~~
* @deprecated 废弃,不再使用,请使用新的 {@link import("./v2/EvenfManager).manager}。另外,如果你使用了此LegacyEvent中的自定义事件,webpack打包或者类似的操作将无法完成。
*/
class Listener {
static #callbacks = [];
static #index = 0;
//这个方法不推荐使用,但是调试用起来是很方便
static _getCallback(id) {
if (debug)
return this.#callbacks[id];
}
//static #callbackInterrupttedCount = (debug) ? new Map() : undefined;
/*
static #checkIsFireInterrupted(oid){
if (oid !== -1){
if (debug){
let s = this.#callbackInterrupttedCount.get(oid);
s = (s !== undefined) ? s+1 : 1;
this.#callbackInterrupttedCount.set(oid, s);
logger.warning("在回调{}时意外终止,已发生{}次", oid, s);
} else {
logger.warning("在回调时意外终止");
}
}
}
static #fireingCallbackId = -1;
*/
static #fireCallback(id, ...args) {
//this.#checkIsFireInterrupted(this.#fireingCallbackId);
if (!(id in this.#callbacks))
return;
let func = this.#callbacks[id];
//this.#fireingCallbackId = id;
if (Object.prototype.toString.call(func) === "[object AsyncFunction]") {
func(...args)
.then(() => {
logger.trace("完成了ID为 {} 的事件异步回调", id);
})
.catch((err) => {
logger.error("尝试对事件进行ID为 {} 的异步回调时发生错误 {}", id, err);
});
//this.#fireingCallbackId = -1;
return;
}
try {
return func(...args);
}
catch (err) {
logger.error("尝试对事件进行ID为 {} 的回调时发生错误 {}", id, err);
}
//this.#fireingCallbackId = -1;
return;
}
static #delayRegister(idx, eventType, callback, ...eventFilters) {
let idInfo = getIdentifierInfo(eventType);
let eventName = idInfo.id;
EventRegisterListener.add(idInfo.id, async () => {
eventType = EventTypes.get(eventType);
this.#doDelayRegister({
eventName, idx,
args: [idx, eventType, callback, ...eventFilters]
});
});
return idx;
}
static #doDelayRegister(options) {
let { eventName, idx, args } = options;
try {
this.#doRegister(...args);
logger.debug("已完成对事件{}的回调{}的注册", eventName, idx);
}
catch {
logger.error("未能完成对事件{}的延迟注册回调{}", eventName, idx);
}
}
static #doRegister(idx, eventType, callback, ...eventFilters) {
if (!(eventType?.subscribe instanceof Function)) {
const error = new Error("require a subscribe() to register event");
logger.error("在注册id为{}的回调时发生错误 {}", idx, error);
throw error;
}
if (!(callback instanceof Function)) {
const error = new TypeError("not a function");
logger.error("在注册id为{}的回调时发生错误 {}", idx, error);
throw error;
}
let fireCallback = (...args) => {
this.#fireCallback(idx, ...args);
};
try {
this.#callbacks[idx] = callback;
eventType.subscribe(fireCallback, ...eventFilters);
//logger.trace("已成功注册id为{}的回调", idx);
}
catch (e) {
if (!debug)
delete this.#callbacks[idx];
logger.error("在注册id为{}的回调时发生错误 {}", idx, e);
throw e;
}
}
/**
* add a new callback function for specific event
* @param eventType - the event identify
* @param callback - callback function
* @param eventFilters - any arguments you want, they will be transmitted directly
* @returns {number} - id of the callback
*/
static register(eventType, callback, ...eventFilters) {
let idx = this.#index;
if (eventType?.constructor === String) {
if (EventTypes.has(eventType)) {
eventType = EventTypes.get(eventType);
}
else {
logger.debug("延迟id为{}的{}事件注册", this.#index, eventType);
this.#delayRegister(this.#index, eventType, callback, ...eventFilters);
return this.#index++;
}
}
this.#doRegister(idx, eventType, callback, ...eventFilters);
return this.#index++;
}
/**
* unregister event listener
* @param {number} id - eventId
*/
static unregister(id) {
if (id in this.#callbacks) {
delete this.#callbacks[id];
logger.debug("移除了ID为{}的回调", id);
}
else {
let idx = this.#callbacks.indexOf(id);
if (idx !== -1) {
delete this.#callbacks[idx];
logger.debug("移除了ID为{}的回调", idx);
}
}
}
}
export { Listener, Listener as EventListener };