import { Toolkit } from '../Toolkit'; import * as _ from 'lodash'; import { CanvasEngine } from '../CanvasEngine'; import { BaseEvent, BaseListener, BaseObserver } from '../core/BaseObserver'; import { AbstractModelFactory } from '../core/AbstractModelFactory'; import { BaseModel } from './BaseModel'; export interface BaseEntityEvent extends BaseEvent { entity: T; } export interface BaseEntityListener extends BaseListener { lockChanged?(event: BaseEntityEvent & { locked: boolean }): void; } export type BaseEntityType = 'node' | 'link' | 'port' | 'point'; export interface BaseEntityOptions { id?: string; locked?: boolean; } export type BaseEntityGenerics = { LISTENER: BaseEntityListener; OPTIONS: BaseEntityOptions; }; export interface DeserializeEvent { engine: CanvasEngine; data: ReturnType; registerModel(model: BaseModel); getModel(id: string): Promise; } export class BaseEntity extends BaseObserver { protected options: T['OPTIONS']; constructor(options: T['OPTIONS'] = {}) { super(); this.options = { id: Toolkit.UID(), ...options }; } getOptions() { return this.options; } getID() { return this.options.id; } doClone(lookupTable: { [s: string]: any } = {}, clone: any) { /*noop*/ } clone(lookupTable: { [s: string]: any } = {}) { // try and use an existing clone first if (lookupTable[this.options.id]) { return lookupTable[this.options.id]; } let clone = _.cloneDeep(this); clone.options = { ...this.options, id: Toolkit.UID() }; clone.clearListeners(); lookupTable[this.options.id] = clone; this.doClone(lookupTable, clone); return clone; } clearListeners() { this.listeners = {}; } deserialize(event: DeserializeEvent) { this.options.id = event.data.id; this.options.locked = event.data.locked; } serialize() { return { id: this.options.id, locked: this.options.locked }; } fireEvent & object>(event: L, k: keyof T['LISTENER']) { super.fireEvent( { entity: this, ...event }, k ); } public isLocked(): boolean { return this.options.locked; } public setLocked(locked: boolean = true) { this.options.locked = locked; this.fireEvent( { locked: locked }, 'lockChanged' ); } }