import { Identifier } from "../Engine/Common/Identifier" ; import { GeneralProcess } from "./GeneralProcess" ; export class GeneralInterface { [ name ] : any [ ] ; } type GeneralProcessesType < TThis , T extends GeneralInterface > = { [ P in keyof T ] ? : GeneralProcess < TThis , T [ P ] > ; } ; /**
 * Represent a general object
 */ export class GeneralObject < T extends GeneralInterface > { identifier : number = Identifier . unique ; joints : GeneralObject < any > [ ] = [ ] ; processes : GeneralProcessesType < this , T > = { } ; joint ( object ) { GeneralProcessHelper . combine ( this , object ) ; this . joints . push ( object ) ; object . joints . push ( this ) ; return this ; } disjoint ( object ) { const index = this . joints . indexOf ( object ) ; if ( index >= 0 ) { this . joints . splice ( this . joints . indexOf ( object ) , 1 ) ; object . joints . splice ( object . joints . indexOf ( this ) , 1 ) ; GeneralProcessHelper . seperate ( this , object ) ; return this . disjoint ( object ) ; } return this ; } implements ( generalInterface ) { for ( const key in generalInterface ) { if ( generalInterface [ key ] instanceof Array ) { if ( ! this . processes [ key ] ) { this . processes [ key ] = new GeneralProcess ( this ) . next ( ( this as any ) [ key ] ) ; } } } } } interface GeneralProcessKeyValuePair { key : string ; value : GeneralProcess < any , any > ; } class GeneralProcessHelper { static find ( object ) { const result = [ ] ; const processes = object . processes ; for ( const key in processes ) { result . push ( { key : key , value : processes [ key ] } ) ; } return result ; } static combine ( source , target ) { this . every ( source , target , ( s , t ) => { s . next ( ( s , ... args ) => t . process ( source , ... args ) , target . identifier ) ; } ) ; } static seperate ( source , target ) { this . every ( source , target , ( s ) => { s . remove ( target . identifier ) ; } ) ; } private static every ( source , target , hanlder ) { const sourceProcesses = source . processes ; const targetProcesses = target . processes ; this . find ( source ) . forEach ( element => { const sourceProcess = sourceProcesses [ element . key ] ; const targetProcess = targetProcesses [ element . key ] ; if ( targetProcess instanceof GeneralProcess ) { hanlder ( sourceProcess , targetProcess , element . key ) ; } } ) ; } }