yoni-mcscripts-lib
Version:
为 Minecraft Script API 中的部分接口创建了 wrapper,并提供简单的事件管理器和任务管理器,另附有一些便于代码编写的一些小工具。
291 lines (260 loc) • 10.1 kB
text/typescript
import EventListeningAdapter from "./interfaces/EventListeningAdapter";
import IEventHandler from "./interfaces/EventHandler";
import { manager } from "./EventManager.js";
import { defaultOptionResolver } from "./lib/defaultOptionResolver.js";
import { EventPriority, EventPriorityIds } from "./EventPriority.js";
import { getExtendedClassesInList } from "./lib/getExtendedClassesInList.js";
import { EventOptionType } from "./GetEventOptions";
export class EventRegistry<TEvent extends Function> {
if (this.
throw new TypeError("Deny changing the event info as it was registered");
}
throwIfNotRegistered(){
if (!this.
throw new TypeError("The event info is not registered");
}
/**
* 该事件的便于区分的名字。
*/
get eventName(){
return this.
}
/**
* 关联到的事件类。
*/
readonly eventClass: TEvent;
/**
* 指定不扩展此事件的范围。
*/
get noExtends(): boolean {
return this.
}
set noExtends(v: boolean){
this.
this.
}
/**
* 指定此事件使用额外参数在handler前过滤事件。
*/
get extraOption(): boolean {
return this.
}
set extraOption(v: boolean){
this.
this.
}
/**
* 此事件在handler前过滤事件所使用的处理器。
*/
get extraOptionResolver(): ExtraOptionResolver<TEvent> | undefined {
return this.
}
set extraOptionResolver(v: ExtraOptionResolver<TEvent> | undefined){
this.
this.
}
/**
* 此事件的兼容监听器。
*/
get listeningAdapter(): EventListeningAdapter<TEvent> | undefined {
return this.
}
set listeningAdapter(v: EventListeningAdapter<TEvent> | undefined){
this.
this.
}
/**
* 兼容监听器是否已经启用。
*/
/**
* 处理兼容监听器。
*/
if (!this.listeningAdapter)
return false;
if (action === "enable" && !this.
this.listeningAdapter.listen(receiveEvent);
this.
} else if (action === "disable" && this.
if (this.listeningAdapter.remove()){
this.
}
} else {
return false;
}
const eventRegistry = this;
function receiveEvent(event: TEvent){
manager.callEvent(eventRegistry, event);
}
return true;
}
/**
* will initialize on {@link EventRegistry##sortHandlers}
*/
get
return this.
}
set
if (!hasSorted)
this.
}
if (this.
return;
const sortedHandlersList = EventPriorityIds
.sort((va, vb) => va - vb)
.map(id => this.handlerslots.get(id) as IEventHandler<TEvent>[])
.flat();
this.
this.
}
get handlers(){
this.
return this.
}
handlerslots: Map<EventPriority, IEventHandler<TEvent>[]> = new Map(
// 此处为每个事件优先级初始化一个用于存储事件处理器的列表
EventPriorityIds.map(prio => [
prio as EventPriority,
[] as IEventHandler<TEvent>[]
])
);
get hasRegistered(){
return this.
}
private constructor(eventClass: TEvent){
// 多一次无用操作起码比类型报错好
this.eventClass = eventClass;
Object.defineProperty(this, "eventClass", { value: eventClass });
}
addHandler(handler: IEventHandler<TEvent>, priority: EventPriority){
if ((this.handlerslots.get(priority) as IEventHandler<TEvent>[]).includes(handler)){
throw new Error("registered");
}
this.
this.handlerslots.get(priority)?.push(handler); //实际上不会也不应该出现空槽位结果,除非传入的priority不正确
this.
}
removeHandler(handler: IEventHandler<TEvent>, priority: EventPriority): boolean {
const handlers = this.handlerslots.get(priority) as IEventHandler<TEvent>[];
const location = handlers.indexOf(handler);
if (location === -1){
return false;
}
this.
handlers.splice(location, 1);
return true;
}
/**
* 注销事件信息。
*/
static unregister<TEvent extends Function>(eventClass: TEvent | EventRegistry<TEvent>): boolean {
if (eventClass instanceof EventRegistry)
eventClass = eventClass.eventClass;
if (!EventRegistry.
return false;
}
const registry = EventRegistry.
registry.handlerslots.clear(); //看上去这会破坏什么东西
registry.
registry.
registry.
EventRegistry.
EventRegistry.
return true;
}
/**
* 注册事件信息。
*/
static register<TEvent extends Function>(eventClass: EventRegistry<TEvent> | TEvent, option?: EventRegisterOptions<TEvent>): EventRegistry<TEvent> {
let registry;
if (eventClass instanceof EventRegistry){
registry = eventClass;
eventClass = registry.eventClass;
} else {
registry = new EventRegistry<TEvent>(eventClass);
}
registry.
if (option){
EventRegistry.
}
if (registry.
&& !registry.
&& registry.handlers.length !== 0){
registry.
}
registry.
EventRegistry.
EventRegistry.
return registry;
}
static
eventRegistry.
eventRegistry.noExtends = option.noExtends ?? eventRegistry.noExtends;
eventRegistry.extraOption = option.extraOption ?? eventRegistry.extraOption;
eventRegistry.extraOptionResolver = option.extraOptionResolver ?? defaultOptionResolver;
eventRegistry.listeningAdapter = option.listeningAdapter ?? eventRegistry.listeningAdapter;
eventRegistry.
}
/**
* 获取一个事件所对应的事件信息对象。
*/
static getRegistry<TEvent extends Function>(eventClass: TEvent): EventRegistry<TEvent> {
let registry = EventRegistry.
if (registry != null){
return registry as unknown as EventRegistry<TEvent>;
}
const newRegistry = new EventRegistry<TEvent>(eventClass);
EventRegistry.
return newRegistry;
}
static getExtends<
T extends EventRegistry<TEvent>,
TEvent extends Function = T["eventClass"]
>(registry: T): EventRegistry<Function>[] {
const extendsClasses = EventRegistry.
const matchedClasses = [];
for (const clazz of extendsClasses){
if (getExtendedClassesInList(clazz, extendsClasses)){
matchedClasses.push(clazz);
}
}
return matchedClasses.map(clazz => EventRegistry.getRegistry(clazz));
}
static
static
static get
if (EventRegistry.
return EventRegistry.
}
const extendsClasses: Function[] = [];
for (const er of EventRegistry.
if (!er.noExtends){
extendsClasses.push(er.eventClass);
}
}
EventRegistry.
return extendsClasses;
}
}
/**
* 事件注册所需要的信息。
*/
export interface EventRegisterOptions<TEvent extends Function> {
noExtends?: boolean
extraOption?: boolean
extraOptionResolver?: ExtraOptionResolver<TEvent>
listeningAdapter?: EventListeningAdapter<TEvent>
displayName?: string
}
export type ExtraOptionResolver<TEvent extends Function> = (event: Prototype<TEvent>, option: EventOptionType<Prototype<TEvent>>) => boolean
type Prototype<TFunction extends Function> = TFunction["prototype"];