import { ICommands } from "./commands.spec" ; import { IEntity } from "../entity.spec" ; import { TTypeProto } from "../_.spec" ; import { ISerialFormat } from "../serde/serial-format.spec" ; import { TDeserializer , TSerDeOptions } from "../serde/serde.spec" ; import IWorld , { TGroupHandle } from "../world.spec" ; import { IIStateProto } from "../state.spec" ; import { World } from "../world" ; import { ICommandsAggregator , TCommand } from "./commands-aggregator.spec" ; import { CommandEntityBuilder } from "./command-entity-builder" ; export * from "./commands.spec" ; export class Commands implements ICommands { constructor ( public readonly world , public readonly aggregator ) { } addEntity ( entity ) { this . aggregator . addCommand ( ( ) => this . world . addEntity ( entity ) ) ; } addResource < T extends Object > ( obj , ... args ) { let type ; let instance ; if ( typeof obj === 'object' ) { type = obj . constructor as TTypeProto < T > ; instance = obj ; } else { type = obj ; instance = new ( obj . prototype . constructor . bind ( obj , ... Array . from ( arguments ) . slice ( 1 ) ) ) ( ) ; } if ( this . world . resources . has ( type ) ) { throw new Error ( `Resource with name "${ type . name }" already exists!` ) ; } this . aggregator . addCommand ( ( ) => { if ( this . world . resources . has ( type ) ) { throw new Error ( `Resource with name "${ type . name }" already exists!` ) ; } this . world . resources . set ( type , instance ) ; } ) ; return instance ; } buildEntity ( ) { return new CommandEntityBuilder ( this ) ; } clearEntities ( ) { this . aggregator . addCommand ( ( ) => this . world . entities . clear ( ) ) ; } load ( prefab , options ? ) { const handle = this . world . groups . nextHandle ++ ; this . aggregator . addCommand ( ( ) => { this . world . load ( prefab , options , handle ) ; } ) ; return handle ; } maintain ( ) { this . aggregator . triggerMaintain ( ) ; } merge ( world ) { const handle = this . world . groups . nextHandle ++ ; this . aggregator . addCommand ( ( ) => { this . world . merge ( world , handle ) ; } ) ; return handle ; } popState ( ) { this . aggregator . addCommand ( ( ) => this . world . popState ( ) ) ; } pushState ( NewState ) { this . aggregator . addCommand ( ( ) => this . world . pushState ( NewState ) ) ; } queueCommand ( command ) { this . aggregator . addCommand ( command ) ; } removeEntity ( entity ) { this . aggregator . addCommand ( ( ) => this . world . removeEntity ( entity ) ) ; } removeResource < T extends Object > ( type ) { if ( ! this . world . resources . has ( type ) ) { throw new Error ( `Resource with name "${ type . name }" does not exists!` ) ; } this . aggregator . addCommand ( ( ) => { if ( ! this . world . resources . has ( type ) ) { throw new Error ( `Resource with name "${ type . name }" does not exists!` ) ; } this . world . resources . delete ( type ) ; } ) ; } replaceResource < T extends Object > ( obj , ... args ) { let type ; if ( typeof obj === 'object' ) { type = obj . constructor as TTypeProto < T > ; } else { type = obj ; } if ( ! this . world . resources . has ( type ) ) { throw new Error ( `Resource with name "${ type . name }" does not exists!` ) ; } this . aggregator . addCommand ( ( ) => { if ( ! this . world . resources . has ( type ) ) { throw new Error ( `Resource with name "${ type . name }" does not exists!` ) ; } this . world . resources . delete ( type ) ; this . world . addResource ( obj , ... args ) ; } ) ; } stopRun ( ) { this . aggregator . addCommand ( ( ) => this . world . stopRun ( ) ) ; } unloadPrefab ( handle ) { this . aggregator . addCommand ( ( ) => this . world . unloadPrefab ( handle ) ) ; } }