import { Arrays } from "../tools/Arrays"; import { EventSlot } from "./EventSlot"; export enum ListPropertyEventType { ADDED, REMOVED, CHANGED, SWAPPED } export class ListPropertyEvent { type:ListPropertyEventType; indices:number[] = []; elements:T[] = [] static create( type:ListPropertyEventType, indices:number[], elements:T[] ) { let e = new ListPropertyEvent(); e.type = type; e.indices = indices; e.elements = elements; return e; } } export class ListProperty extends EventSlot> { #list:T[] = []; #dispatch( type:ListPropertyEventType, indices:number[], elements:T[] ) { this.dispatch( ListPropertyEvent.create( type, indices, elements ) ); } #dispatchAdded( indices:number[], elements:T[] ) { this.#dispatch( ListPropertyEventType.ADDED, indices, elements ); } #dispatchRemoved( indices:number[], elements:T[] ) { this.#dispatch( ListPropertyEventType.REMOVED, indices, elements ); } #dispatchChanged( indices:number[], elements:T[] ) { this.#dispatch( ListPropertyEventType.CHANGED, indices, elements ); } #dispatchSwapped( indices:number[], elements:T[] ) { this.#dispatch( ListPropertyEventType.SWAPPED, indices, elements ); } get length() { return this.#list.length; } indexOf( t:T ) { return this.#list.indexOf( t ); } forAll( callback:( t:T, index:number ) => void ) { for ( let i = 0; i < this.#list.length; i++ ) { callback( this.#list[ i ], i ); } } add( t:T ) { this.#list.push( t ); this.#dispatchAdded( [ this.#list.length - 1 ], [ t ] ); } addAll( all:T[] ) { let last = this.#list.length; this.#list = this.#list.concat( all ); this.#dispatchAdded( [ last ], all ); } get( index:number ) { return this.#list[ index ]; } set( index:number, t:T ) { let before = this.#list[ index ]; this.#list[ index ] = t; this.#dispatchChanged( [ index ], [ before, t ] ); } remove( index:number ) { let removal = this.#list[ index ]; Arrays.removeAt( this.#list, index ); this.#dispatchRemoved( [ index ], [ removal ] ); } removeFirst() { if ( this.length < 1 ) { return; } this.remove( 0 ); } removeLast() { if ( this.length < 1 ) { return; } this.remove( this.length - 1 ); } clear() { let all = this.#list; this.#list = []; this.#dispatchRemoved( null, all ); } swap( indexA:number, indexB:number ) { let elementA = this.#list[ indexA ]; let elementB = this.#list[ indexB ]; this.#list[ indexA ] = elementB; this.#list[ indexB ] = elementA; this.#dispatchSwapped( [ indexA, indexB ], [ elementB, elementA ] ); } }