import * as I from 'immutable'; import {compose} from '@avocado/core'; import {EventEmitter} from '@avocado/mixins'; import {Layer} from './layer'; const decorate = compose( EventEmitter, ); export class Layers extends decorate(class {}) { constructor() { super(); this.layers = {}; this._state = I.Map(); this.onEntityAddedToLayers = this.onEntityAddedToLayers.bind(this); this.onEntityRemovedFromLayers = this.onEntityRemovedFromLayers.bind(this); } *[Symbol.iterator]() { for (const index in this.layers) { const layer = this.layers[index]; yield {index, layer}; } } acceptStateChange(change) { for (const index in change) { const layer = this.layers[index] ? this.layers[index] : new Layer(); if (!this.layers[index]) { this.addLayer(index, layer); } layer.acceptStateChange(change[index]); } } addEntityToLayer(entity, layerIndex) { const layer = this.layers[layerIndex]; if (!layer) { return; } layer.addEntity(entity); } addLayer(index, layer) { layer.on('entityAdded', this.onEntityAddedToLayers); layer.on('entityRemoved', this.onEntityRemovedFromLayers); this.layers[index] = layer; this.emit('layerAdded', layer, index); } destroy() { for (const index in this.layers) { const layer = this.layers[index]; this.removeLayer(index); layer.destroy(); } } findEntity(uuid) { for (const index in this.layers) { const layer = this.layers[index]; const foundEntity = layer.findEntity(uuid); if (foundEntity) { return foundEntity; } } } fromJSON(json) { if (json) { for (const index in json) { const layerJSON = json[index]; const layer = new Layer() this.addLayer(index, layer); layer.fromJSON(layerJSON); } } return this; } layer(index) { return this.layers[index]; } onEntityAddedToLayers(entity) { this.emit('entityAdded', entity); } onEntityRemovedFromLayers(entity) { this.emit('entityRemoved', entity); } removeEntityFromLayer(entity, layerIndex) { const layer = this.layers[layerIndex]; if (!layer) { return; } layer.removeEntity(entity); } removeLayer(index) { const layer = this.layers[index]; if (!layer) { return; } layer.off('entityAdded', this.onEntityAddedToLayers); layer.off('entityRemoved', this.onEntityRemovedFromLayers); delete this.layers[index]; this.emit('layerRemoved', layer, index); } get state() { return this._state; } tick(elapsed) { if (this.layers) { for (const index in this.layers) { const layer = this.layers[index]; layer.tick(elapsed); this._state = this._state.set(index, layer.state); } } } }