import * as I from 'immutable'; import {arrayUnique, compose, flatten} from '@avocado/core'; import {EventEmitter} from '@avocado/mixins'; import {Synchronized} from '@avocado/state'; import {Layer} from './layer'; const decorate = compose( EventEmitter, ); export class Layers extends decorate(Synchronized) { constructor() { super(); this.layers = {}; } *[Symbol.iterator]() { for (const index in this.layers) { const layer = this.layers[index]; yield {index, layer}; } } addEntityToLayer(entity, layerIndex) { const layer = this.layers[layerIndex]; if (!layer) { return; } layer.addEntity(entity); } addLayer(index, layer) { layer.on('entityAdded', this.onEntityAddedToLayers, this); layer.on('entityRemoved', this.onEntityRemovedFromLayers, this); 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); } patchStateStep(index, step) { const layer = this.layers[index] ? this.layers[index] : new Layer(); if (!this.layers[index]) { this.addLayer(index, layer); } layer.patchState([step]); } 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); } tick(elapsed) { if (this.layers) { for (const index in this.layers) { const layer = this.layers[index]; layer.tick(elapsed); } this.state = this.state.withMutations((state) => { for (const index in this.layers) { const layer = this.layers[index]; state.set(index, layer.state); } }); } } visibleEntities(query) { const layerEntities = []; for (const {index, layer} of this) { layerEntities.push(layer.visibleEntities(query)); } return arrayUnique(flatten(layerEntities)); } }