import { Container } from "pixi.js" ; import { EventDispatcher } from "@robotlegsjs/core" ; import { ContainerBinding } from "./ContainerBinding" ; import { ContainerBindingEvent } from "./ContainerBindingEvent" ; import { ContainerRegistryEvent } from "./ContainerRegistryEvent" ; private export class ContainerRegistry extends EventDispatcher { private _bindings : ContainerBinding [ ] = [ ] ; private public get bindings ( ) : ContainerBinding [ ] { return this . _bindings ; } private _rootBindings : ContainerBinding [ ] = [ ] ; private public get rootBindings ( ) : ContainerBinding [ ] { return this . _rootBindings ; } private _bindingByContainer : Map < Container , ContainerBinding > = new Map < Container , ContainerBinding > ( ) ; private public addContainer ( container ) { let binding = this . _bindingByContainer . get ( container ) ; if ( ! binding ) { binding = this . createBinding ( container ) ; this . _bindingByContainer . set ( container , binding ) ; } return binding ; } private public removeContainer ( container ) { let binding = this . _bindingByContainer . get ( container ) ; if ( binding ) { this . removeBinding ( binding ) ; } return binding ; } private public findParentBinding ( target ) { let parent = target . parent ; while ( parent ) { let binding = this . _bindingByContainer . get ( parent ) ; if ( binding ) { return binding ; } parent = parent . parent ; } return null ; } private public getBinding ( container ) { return this . _bindingByContainer . get ( container ) ; } private createBinding ( container ) { let binding = new ContainerBinding ( container ) ; this . _bindings . push ( binding ) ; binding . addEventListener ( ContainerBindingEvent . BINDING_EMPTY , this . onBindingEmpty . bind ( this ) ) ; binding . parent = this . findParentBinding ( container ) ; if ( binding . parent == null ) { this . addRootBinding ( binding ) ; } this . _bindingByContainer . forEach ( childBinding => { if ( container . contains ( childBinding . container ) ) { if ( ! childBinding . parent ) { this . removeRootBinding ( childBinding ) ; childBinding . parent = binding ; } else if ( ! container . contains ( childBinding . parent . container ) ) { childBinding . parent = binding ; } } } ) ; this . dispatchEvent ( new ContainerRegistryEvent ( ContainerRegistryEvent . CONTAINER_ADD , binding . container ) ) ; return binding ; } private removeBinding ( binding ) { this . _bindingByContainer . delete ( binding . container ) ; let index = this . _bindings . indexOf ( binding ) ; this . _bindings . splice ( index , 1 ) ; binding . removeEventListener ( ContainerBindingEvent . BINDING_EMPTY , this . onBindingEmpty ) ; if ( ! binding . parent ) { this . removeRootBinding ( binding ) ; } this . _bindingByContainer . forEach ( childBinding => { if ( childBinding . parent === binding ) { childBinding . parent = binding . parent ; if ( ! childBinding . parent ) { this . addRootBinding ( childBinding ) ; } } } ) ; this . dispatchEvent ( new ContainerRegistryEvent ( ContainerRegistryEvent . CONTAINER_REMOVE , binding . container ) ) ; } private addRootBinding ( binding ) { this . _rootBindings . push ( binding ) ; this . dispatchEvent ( new ContainerRegistryEvent ( ContainerRegistryEvent . ROOT_CONTAINER_ADD , binding . container ) ) ; } private removeRootBinding ( binding ) { let index = this . _rootBindings . indexOf ( binding ) ; this . _rootBindings . splice ( index , 1 ) ; this . dispatchEvent ( new ContainerRegistryEvent ( ContainerRegistryEvent . ROOT_CONTAINER_REMOVE , binding . container ) ) ; } private onBindingEmpty ( event ) { this . removeBinding ( < any > event . target ) ; } }