UNPKG

yoni-mcscripts-lib

Version:

为 Minecraft Script API 中的部分接口创建了 wrapper,并提供简单的事件管理器和任务管理器,另附有一些便于代码编写的一些小工具。

101 lines (100 loc) 4.06 kB
import { sEventListenerData } from "./decorators/EventListener.js"; import { logger } from "./logger.js"; import { EventError } from "./EventError.js"; import { EventRegistry } from "./EventRegistry.js"; import { isDebug, config } from "../config.js"; import { listenEvent } from "./lib/listenEvent.js"; export class EventManager { /** * 处理事件回调要求的额外参数。 */ static checkExtraOption(eventRegistry, handler, event) { if (!eventRegistry.extraOption || !handler.options || !eventRegistry.extraOptionResolver) { return true; } try { return eventRegistry.extraOptionResolver(event, handler.options); } catch (e) { if (isDebug() || config.getConfig("eventManager.showErrorOfEventFilter")) logger.warn("处理事件过滤器时发生以下错误:", e); } return false; } /** * 处理一次事件。 * @param eventRegistry 事件的注册信息。 * @param event 事件对象。 * @param noExtendsAlways 指定是否不应该去尝试扩展事件的回调范围。 */ callEvent(eventRegistry, event, noExtendsAlways = false) { eventRegistry.throwIfNotRegistered(); if (!noExtendsAlways && !eventRegistry.noExtends) { let extendsEvents = EventRegistry.getExtends(eventRegistry); for (const registry of extendsEvents) { this.callEvent(registry, event, true); } } try { for (const handler of eventRegistry.handlers) { if (handler.ignoreCancelled && "cancel" in event && event.cancel) { continue; //跳过,由于处理器不接受已取消事件 } if (!EventManager.checkExtraOption(eventRegistry, handler, event)) { continue; } try { //捕获事件处理错误,并输出日志 handler.onEvent(event); } catch (e) { logger.error("处理事件 {} 时发生以下错误:", eventRegistry.eventName, e); } } } catch (e) { //捕获事件执行错误,应该抛出(不过我也不知道这里能捕获到什么错误) //re-throw EventError const error = new EventError(eventRegistry, event, e); if (isDebug()) logger.error(error); throw error; } } addListener(listener) { if (!(sEventListenerData in listener)) throw new TypeError("not a listener"); const cListener = listener; const data = cListener[sEventListenerData]; if (data.registeredListeners.size === 0) for (const entries of data.handlerEntries) { const [tevent, prio, handler] = entries; EventRegistry.getRegistry(tevent).addHandler(handler, prio); } if (data.registeredListeners.has(listener)) throw new Error("the listener already been registered"); data.registeredListeners.add(listener); } removeListener(listener) { if (!(sEventListenerData in listener)) throw new TypeError("not a listener"); const cListener = listener; const data = cListener[sEventListenerData]; if (!data.registeredListeners.has(listener)) return false; data.registeredListeners.delete(listener); if (data.registeredListeners.size === 0) for (const entries of data.handlerEntries) { const [tevent, prio, handler] = entries; EventRegistry.getRegistry(tevent).removeHandler(handler, prio); } return true; } listenEvent(listenOptions, callback) { return listenEvent(listenOptions, callback); } } export const eventManager = new EventManager(); export { eventManager as manager };