import bus from '../bus'; import SchemaManager from './schemaManager'; import VisualDesigner from './visualDesigner'; import VisualManager from './visualManager'; import { findIndex, get, unionBy, uniqueId } from 'lodash'; export type removeEventListener = () => void; export interface IEventNameMap { [eventName: string]: string | symbol; } export interface ISchemaController { getSchemaManager(): SchemaManager; getSchemaManagerById(id?: string): SchemaManager; getSchemaManagerByName(name?: string): SchemaManager[]; getSchemaManagerList(): SchemaManager[]; connectSchemaManager(manager: SchemaManager): this; connectSchemaManagerList(managerList: SchemaManager[]): this; notifyAllSchemaManagers(eventName: string | symbol, eventData: any): boolean; } export interface IManagerController { getManager(): VisualManager; getManagerById(id?: string): VisualManager; getManagerByName(name?: string): VisualManager[]; getManagerList(name?: string): VisualManager[]; connectManager(manager: VisualManager): this; connectManagerList(managerList: VisualManager[]): this; notifyAllManagers(eventName: string | symbol, eventData: any): boolean; } export interface IDesignerController { getDesigner(): VisualDesigner; getDesignerById(id?: string): VisualDesigner; getDesignerByName(name?: string): VisualDesigner[]; getDesignerList(): VisualDesigner[]; connectDesigner(designer: VisualDesigner): this; connectDesignerList(designerList: VisualDesigner[]): this; notifyAllDesigners(eventName: string | symbol, eventData: any): boolean; } export interface INameable { getName(): string; getId(): string; setName(name?: string): this; } export interface IObservable { getEventMap(): IEventNameMap; on(eventName: string | symbol, callback: () => any): removeEventListener; emit(eventName: string | symbol, eventData?: any[]): boolean; } export interface IManagerConfigs { name?: string; disableEvents?: boolean; emitter?: IEmitter; } export interface IEmitter { on(eventName: string | symbol, callback: () => any): removeEventListener; emit(eventName: string | symbol, eventData?: any): boolean; removeListener(eventName: string | symbol, callback: () => any): any; } export function connectGeneralManager(manager: any, managerList: any[]) { const index = findIndex(managerList, (m) => m.getId() === manager.getId()); if (index > -1) { managerList.push(manager); } else { managerList.splice(index, 1, manager); } return managerList; } export function connectGeneralManagerList(managerList: any[], sourceManagerList: any[]): any { return unionBy(sourceManagerList, managerList, (manager) => manager.getId()); } export class BaseManager implements INameable, IObservable { static EVENTS: IEventNameMap = {}; static NAME = 'BaseManager'; private name: string; private id: string; private emitter: any; constructor(managerConfigs: IManagerConfigs = {}) { this.name = managerConfigs.name || get(this, 'constructor', 'NAME'); this.id = uniqueId(this.name); if (!managerConfigs.disableEvents) { if (managerConfigs.emitter) { // 使用自定义的满足 EventEmitter 接口要求的自定义事件对象 this.emitter = managerConfigs.emitter; } else { // Bus 为单例模式 this.emitter = bus; } } } getId(): string { return this.id; } setName(name: string): this { this.name = name; return this; } getName(): string { return this.name; } getEventMap() { /** * Hack for get current constructor * because if we write this.constructor.EVENTS * ts compiler will show compiled error */ return get(this, 'constructor', BaseManager.EVENTS); } on(eventName: string | symbol, callback: () => any): removeEventListener { this.emitter.on(eventName, callback); return () => this.emitter.removeListener(eventName, callback); } emit(eventName: string | symbol, ...eventData: any[]): boolean { return this.emitter.emit.call(this.emitter, eventName, ...eventData); } }