avocado-old/packages/topdown/layers.js

132 lines
2.9 KiB
JavaScript

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 = {};
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};
}
}
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);
}
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.set(index, layer.state);
}
}
}
visibleEntities(query) {
const layerEntities = [];
for (const {index, layer} of this) {
layerEntities.push(layer.visibleEntities(query));
}
return arrayUnique(flatten(layerEntities));
}
}