UNPKG

@turbox3d/reactivity

Version:

Large-scale reactive state management library

94 lines (86 loc) 3.14 kB
import { fail } from '@turbox3d/shared'; import { ctx } from '../const/config'; import { ECollectType } from '../const/enums'; import { KeyPathType } from '../core/domain'; import { MaterialCallStackRecord } from './materialCallStack'; export enum EEventName { storeOnActive = 'storeOnActive', beforeStoreChange = 'beforeStoreChange', afterStoreChange = 'afterStoreChange', asyncAfterStoreChange = 'asyncAfterStoreChange', setProperty = 'setProperty', materialCallStackChange = 'materialCallStackChange', } export interface SetPropertyEvent { stackId?: number; domain: string; keyPath: Array<{ type: KeyPathType; value: string }>; newValue: any; oldValue: any; time: number; type: ECollectType; } export interface BeforeStoreChangeEvent { domain?: string; method: string; args: any[]; state: any; time: number; stackId?: number; } export interface AfterStoreChangeEvent { domain?: string; method: string; args: any[]; state: any; async: boolean; time: number; stackId?: number; } export interface MaterialCallStackChangeEvent { stack: MaterialCallStackRecord[]; action: 'POP' | 'PUSH'; time: number; currentStack?: MaterialCallStackRecord; } class Emitter { private listeners = {}; on(eventName: EEventName.storeOnActive, callback: () => void): void; on(eventName: EEventName.setProperty, callback: (event: SetPropertyEvent) => void): void; on(eventName: EEventName.beforeStoreChange, callback: (event: BeforeStoreChangeEvent) => void): void; on(eventName: EEventName.afterStoreChange, callback: (event: AfterStoreChangeEvent) => void): void; on(eventName: EEventName.asyncAfterStoreChange, callback: (event: AfterStoreChangeEvent) => void): void; on(eventName: EEventName.materialCallStackChange, callback: (event: MaterialCallStackChangeEvent) => void): void; on(eventName: EEventName, callback: (...args: any[]) => void) { const listeners = this.listeners[eventName] || []; listeners.push(callback); this.listeners[eventName] = listeners; } emit(eventName: EEventName.storeOnActive): void; emit(eventName: EEventName.setProperty, args: SetPropertyEvent): void; emit(eventName: EEventName.beforeStoreChange, args: BeforeStoreChangeEvent): void; emit(eventName: EEventName.afterStoreChange, args: AfterStoreChangeEvent): void; emit(eventName: EEventName.asyncAfterStoreChange, args: AfterStoreChangeEvent): void; emit(eventName: EEventName.materialCallStackChange, args: MaterialCallStackChangeEvent): void; emit(eventName: EEventName, args?: any): void { if (ctx.devTool && window && (window as any).__TURBOX_DEVTOOL_GLOBAL_HOOKS__) { (window as any).__TURBOX_DEVTOOL_GLOBAL_HOOKS__.emit(eventName, args); } const listeners = this.listeners[eventName]; if (!Array.isArray(listeners)) return; listeners.forEach(callback => { try { callback.apply(this, [args]); } catch (e) { fail(e); } }); } off(eventName: EEventName) { if (!this.listeners[eventName]) { return; } this.listeners[eventName] = []; } } export const emitter = new Emitter();