Browse Source
- 重构 `config/index.ts` 中的热更新 URL 配置格式,增加可读性。 - 新增 `packages/base/event/main/index.ts` 基础事件系统实现,支持基本事件监听和触发。 - 新增 `packages/base/event/main/index copy.ts` 增强版事件系统,支持优先级排序和更多特性。 - 修改 `packages/logger/main.ts` 日志模块,改用全局配置而非设置模块,并适配feat/优化
6 changed files with 188 additions and 5 deletions
@ -0,0 +1,123 @@ |
|||
type FireFN = (...argu: any[]) => void |
|||
|
|||
// 监听器类型定义,支持优先级
|
|||
interface Listener<F extends FireFN> { |
|||
fn: F |
|||
once: boolean |
|||
priority: number |
|||
} |
|||
|
|||
class FireEvent<T extends Record<string | symbol, FireFN>> { |
|||
// 使用 Map 存储事件监听器,支持 symbol 键
|
|||
private events = new Map<keyof T, Array<Listener<T[keyof T]>>>() |
|||
|
|||
// 获取事件监听器列表,如果不存在则创建
|
|||
private getListeners<S extends keyof T>(name: S): Array<Listener<T[S]>> { |
|||
if (!this.events.has(name)) { |
|||
this.events.set(name, []) |
|||
} |
|||
return this.events.get(name) as Array<Listener<T[S]>> |
|||
} |
|||
|
|||
// 按优先级排序监听器
|
|||
private sortListeners<S extends keyof T>(name: S) { |
|||
const listeners = this.getListeners(name) |
|||
listeners.sort((a, b) => b.priority - a.priority) |
|||
} |
|||
|
|||
// 打印事件和监听器信息
|
|||
print() { |
|||
console.log("Registered Events:") |
|||
this.events.forEach((listeners, name) => { |
|||
// 显式处理 symbol 类型
|
|||
const keyType = typeof name === "symbol" ? `Symbol(${name.description || ""})` : String(name) |
|||
console.log(` ${keyType}: ${listeners.length} listeners`) |
|||
}) |
|||
} |
|||
|
|||
// 添加事件监听器,支持优先级
|
|||
on<S extends keyof T>(name: S, fn: T[S], priority = 0): this { |
|||
const listeners = this.getListeners(name) |
|||
listeners.push({ fn, once: false, priority }) |
|||
this.sortListeners(name) |
|||
return this // 支持链式调用
|
|||
} |
|||
|
|||
// 触发事件
|
|||
emit<S extends keyof T>(name: S, ...args: Parameters<T[S]>): this { |
|||
const listeners = this.getListeners(name).slice() // 创建副本以避免移除时的问题
|
|||
|
|||
for (const { fn } of listeners) { |
|||
try { |
|||
fn(...args) |
|||
} catch (error) { |
|||
console.error(`Error in event handler for ${String(name)}:`, error) |
|||
} |
|||
} |
|||
|
|||
// 移除一次性监听器
|
|||
if (listeners.some(l => l.once)) { |
|||
this.events.set( |
|||
name, |
|||
this.getListeners(name).filter(l => !l.once), |
|||
) |
|||
} |
|||
|
|||
return this |
|||
} |
|||
|
|||
// 移除事件监听器
|
|||
off<S extends keyof T>(name: S, fn?: T[S]): this { |
|||
if (!this.events.has(name)) return this |
|||
|
|||
const listeners = this.getListeners(name) |
|||
|
|||
if (!fn) { |
|||
// 移除所有监听器
|
|||
this.events.delete(name) |
|||
} else { |
|||
// 移除特定监听器
|
|||
const filtered = listeners.filter(l => l.fn !== fn) |
|||
if (filtered.length === 0) { |
|||
this.events.delete(name) |
|||
} else { |
|||
this.events.set(name, filtered) |
|||
} |
|||
} |
|||
|
|||
return this |
|||
} |
|||
|
|||
// 添加一次性事件监听器
|
|||
once<S extends keyof T>(name: S, fn: T[S], priority = 0): this { |
|||
const listeners = this.getListeners(name) |
|||
listeners.push({ fn, once: true, priority }) |
|||
this.sortListeners(name) |
|||
return this |
|||
} |
|||
|
|||
// 清除所有事件监听器
|
|||
clear(): this { |
|||
this.events.clear() |
|||
return this |
|||
} |
|||
|
|||
// 获取指定事件的监听器数量
|
|||
listenerCount<S extends keyof T>(name: S): number { |
|||
return this.events.get(name)?.length || 0 |
|||
} |
|||
|
|||
// 检查事件是否有监听器
|
|||
hasListeners<S extends keyof T>(name: S): boolean { |
|||
return this.listenerCount(name) > 0 |
|||
} |
|||
|
|||
// 获取所有事件名称
|
|||
eventNames(): Array<keyof T> { |
|||
return Array.from(this.events.keys()) |
|||
} |
|||
} |
|||
|
|||
export function buildEmitter<T extends Record<string | symbol, FireFN>>() { |
|||
return new FireEvent<T>() |
|||
} |
@ -0,0 +1,51 @@ |
|||
// type FireKey = string
|
|||
type FireFN = (...argu: any[]) => void |
|||
|
|||
class FireEvent<T extends Record<string | symbol, FireFN>> { |
|||
#events: Record<keyof T, FireFN[]> = {} as any |
|||
print() { |
|||
Object.keys(this.#events).forEach(key => { |
|||
console.log(`${key}: ${this.#events[key]}\n`) |
|||
}) |
|||
} |
|||
on<S extends keyof T>(name: S, fn: T[S]) { |
|||
if (!this.#events[name]) { |
|||
this.#events[name] = [] |
|||
} |
|||
this.#events[name].push(fn) |
|||
} |
|||
emit<S extends keyof T>(name: S, ...argu: Parameters<T[S]>) { |
|||
if (this.#events[name]) { |
|||
this.#events[name].forEach(fn => { |
|||
fn(...argu) |
|||
}) |
|||
} |
|||
} |
|||
off<S extends keyof T>(name: S, fn?: T[S]) { |
|||
const len = this.#events[name].length |
|||
if (!len) { |
|||
return |
|||
} |
|||
if (!fn) { |
|||
this.#events[name] = [] |
|||
} else { |
|||
for (let i = len - 1; i >= 0; i--) { |
|||
const _fn = this.#events[name][i] |
|||
if (_fn === fn) { |
|||
this.#events[name].splice(i, 1) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
once<S extends keyof T>(name: S, fn: T[S]) { |
|||
const _fn: any = (...argu: any[]) => { |
|||
fn(...argu) |
|||
this.off<S>(name, _fn) |
|||
} |
|||
this.on(name, _fn) |
|||
} |
|||
} |
|||
|
|||
export function buildEmitter<T extends Record<string | symbol, FireFN>>() { |
|||
return new FireEvent<T>() |
|||
} |
@ -0,0 +1,6 @@ |
|||
import { buildEmitter } from "base/event/main" |
|||
import type { IOnFunc } from "setting/main" |
|||
|
|||
export const emitter = buildEmitter<{ |
|||
update: IOnFunc |
|||
}>() |
Loading…
Reference in new issue