138 lines
4.0 KiB
TypeScript

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);
}
}