import { IClass } from "../../matching/IClass" ; import { ICommand } from "../api/ICommand" ; import { ICommandMapping } from "../api/ICommandMapping" ; import { ICommandMappingList } from "../api/ICommandMappingList" ; import { ICommandTrigger } from "../api/ICommandTrigger" ; import { ILogger } from "../../../framework/api/ILogger" ; export type CommandMappingCompareFunction = ( a : ICommandMapping , b : ICommandMapping ) => number ; private export class CommandMappingList implements ICommandMappingList { private _mappingsByCommand : Map < IClass < ICommand > , ICommandMapping > = new Map < IClass < ICommand > , ICommandMapping > ( ) ; private _mappings : ICommandMapping [ ] = [ ] ; private _trigger : ICommandTrigger ; private _processors : Function [ ] ; private _logger : ILogger ; private _compareFunction : CommandMappingCompareFunction ; private _sorted : boolean ; param trigger param processors param logger constructor ( trigger , processors , logger ? ) { this . _trigger = trigger ; this . _processors = processors ; this . _logger = logger ; } inheritDoc public getList ( ) { if ( ! this . _sorted ) { this . sortMappings ( ) ; } return this . _mappings . concat ( ) ; } inheritDoc public withSortFunction ( sorter ) { this . _sorted = false ; this . _compareFunction = sorter ; return this ; } inheritDoc public addMapping ( mapping ) { this . _sorted = false ; this . applyProcessors ( mapping ) ; let oldMapping = this . _mappingsByCommand . get ( mapping . commandClass ) ; if ( oldMapping ) { this . overwriteMapping ( oldMapping , mapping ) ; } else { this . storeMapping ( mapping ) ; if ( this . _mappings . length === 1 ) { this . _trigger . activate ( ) ; } } } inheritDoc public removeMapping ( mapping ) { if ( this . _mappingsByCommand . has ( mapping . commandClass ) ) { this . deleteMapping ( mapping ) ; if ( this . _mappings . length === 0 ) { this . _trigger . deactivate ( ) ; } } } inheritDoc public removeMappingFor ( commandClass ) { let mapping = this . _mappingsByCommand . get ( commandClass ) ; if ( mapping ) { this . removeMapping ( mapping ) ; } } inheritDoc public removeAllMappings ( ) { if ( this . _mappings . length > 0 ) { let list = this . _mappings . concat ( ) ; let length = list . length ; while ( length -- ) { this . deleteMapping ( list [ length ] ) ; } this . _trigger . deactivate ( ) ; } } private storeMapping ( mapping ) { this . _mappingsByCommand . set ( mapping . commandClass , mapping ) ; this . _mappings . push ( mapping ) ; if ( this . _logger ) { this . _logger . debug ( "{0} mapped to {1}" , [ this . _trigger , mapping ] ) ; } } private deleteMapping ( mapping ) { this . _mappingsByCommand . delete ( mapping . commandClass ) ; this . _mappings . splice ( this . _mappings . indexOf ( mapping ) , 1 ) ; if ( this . _logger ) { this . _logger . debug ( "{0} unmapped from {1}" , [ this . _trigger , mapping ] ) ; } } private overwriteMapping ( oldMapping , newMapping ) { if ( this . _logger ) { this . _logger . warn ( "{0} already mapped to {1}\n" + "If you have overridden this mapping intentionally you can use 'unmap()' " + "prior to your replacement mapping in order to avoid seeing this message.\n" , [ this . _trigger , oldMapping ] ) ; } this . deleteMapping ( oldMapping ) ; this . storeMapping ( newMapping ) ; } private sortMappings ( ) { if ( this . _compareFunction != null ) { this . _mappings = this . _mappings . sort ( this . _compareFunction ) ; } this . _sorted = true ; } private applyProcessors ( mapping ) { this . _processors . forEach ( ( processor ) => { processor ( mapping ) ; } ) ; } }