cocos creator教程:框架 - 事件
【muzzik 教程】:框架 - 事件
相信大多数人经常用到事件,那么我们真正需要的其实是什么呢?简单,安全 有这两个就够了
简单
为什么简单,因为我们直接继承了 cc.EventTarget,这是我们 cocos 开发者接触最多的事件类型了
安全
直接上图更有说服力
-
具有事件键提示及注释
-
事件参数注释
-
类型安全
两种实现方式
多参数事件实现了请求接口(等待事件返回)
单参数事件
顾名思义,事件只有一个参数,多参数则包含在一个对象内
好处:写事件协议时比较简单
坏处:派发事件必须存在参数
import * as cc from "cc";
class event<T> extends cc.EventTarget {
key: { [key in keyof T]: key } = new Proxy(Object.create(null), {
get: (target, key) => key,
});
// @ts-ignore
on<T2 extends keyof T, T3 extends (event: T[T2]) => void>(
type_: T2 | T2[],
callback_: T3,
this_?: any,
once_b_?: boolean
): typeof callback_ | null {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.on(v as any, callback_, this_, once_b_);
});
return null;
} else {
return super.on(type_ as any, callback_, this_, once_b_);
}
}
// @ts-ignore
once<T2 extends keyof T, T3 extends (event: T[T2]) => void>(type_: T2 | T2[], callback_: T3, this_?: any): typeof callback_ | null {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.once(v as any, callback_, this_);
});
return null;
} else {
return super.once(type_ as any, callback_, this_);
}
}
// @ts-ignore
off<T2 extends keyof T, T3 extends (event: T[T2]) => void>(type_: T2 | T2[], callback_?: T3, this_?: any): void {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.off(v as any, callback_, this_);
});
} else {
super.off(type_ as any, callback_, this_);
}
}
// @ts-ignore
emit<T2 extends keyof T, T3 extends T[T2]>(type_: T2 | T2[], args_: T3): void {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.emit(v as any, args_);
});
} else {
super.emit(type_ as any, args_);
}
}
// @ts-ignore
hasEventListener<T2 extends keyof T, T3 extends (event: T[T2]) => void>(type_: T2, callback_?: T3, target_?: any): boolean {
return super.hasEventListener(type_ as any, callback_, target_);
}
clear(): void {
return super["clear"]();
}
}
export default event;
使用方式
多参数事件
可以存在多个参数,但是非对象类型的参数没有注释提示,最好把多个参数包含在对象内
好处:和原本的使用方式一致
坏处:写事件协议需要把参数包含在函数类型内
import * as cc from "cc";
class event<T> extends cc.EventTarget {
key: { [key in keyof T]: key } = new Proxy(Object.create(null), {
get: (target, key) => key,
});
// @ts-ignore
on<T2 extends keyof T, T3 extends (...event_: Parameters<T[T2]>) => void>(
type_: T2 | T2[],
callback_: T3,
this_?: any,
once_b_?: boolean
): typeof callback_ | null {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.on(v as any, callback_ as any, this_, once_b_);
});
return null;
} else {
return super.on(type_ as any, callback_ as any, this_, once_b_);
}
}
// @ts-ignore
once<T2 extends keyof T, T3 extends (...event_: Parameters<T[T2]>) => void>(
type_: T2 | T2[],
callback_: T3,
this_?: any
): typeof callback_ | null {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.once(v as any, callback_ as any, this_);
});
return null;
} else {
return super.once(type_ as any, callback_ as any, this_);
}
}
// @ts-ignore
off<T2 extends keyof T, T3 extends (...event_: Parameters<T[T2]>) => void>(type_: T2 | T2[], callback_?: T3, this_?: any): void {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.off(v as any, callback_ as any, this_);
});
} else {
super.off(type_ as any, callback_ as any, this_);
}
}
// @ts-ignore
emit<T2 extends keyof T, T3 extends Parameters<T[T2]>>(type_: T2 | T2[], ...args_: T3): void {
if (Array.isArray(type_)) {
type_.forEach((v) => {
super.emit(v as any, ...args_);
});
} else {
super.emit(type_ as any, ...args_);
}
}
// @ts-ignore
hasEventListener<T2 extends keyof T, T3 extends (...event_: Parameters<T[T2]>) => void>(type_: T2, callback_?: T3, target_?: any): boolean {
return super.hasEventListener(type_ as any, callback_ as any, target_);
}
clear(): void {
return super["clear"]();
}
/** 请求(等待返回) */
// @ts-ignore
request<T2 extends keyof T, T3 extends Parameters<T[T2]>>(type_: T2 | T2[], ...args_: T3): Promise<any>[] {
if (Array.isArray(type_)) {
const result_as: Promise<any>[] = [];
type_.forEach((v) => {
result_as.push(...this._request_single(v, ...args_));
});
return result_as;
} else {
return this._request_single(type_, ...args_);
}
}
/** 请求单个事件 */
// @ts-ignore
private _request_single<T2 extends keyof T, T3 extends Parameters<T[T2]>>(type_: T2, ...args_: T3): Promise<any>[] {
/** 返回值 */
const result_as: Promise<any>[] = [];
/** 回调列表 */
const callback_as: { callback: Function; target?: any }[] = this["_callbackTable"][type_]?.callbackInfos;
if (!callback_as) {
return result_as;
}
callback_as.forEach((v) => {
const old_callback_f = v.callback;
const target = v.target;
v.callback = (...args: any[]) => {
result_as.push(old_callback_f.call(target, ...args));
v.callback = old_callback_f;
};
});
this.emit(type_, ...args_);
return result_as;
}
}
export default event;
使用方式
以上两种都是类型安全的,第二种兼容性更好点
本文来自博客园,作者:Muzzik,转载请注明原文链接:https://www.cnblogs.com/muzzik/p/17044999.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步