2019-03-27 01:52:24 -05:00
|
|
|
import * as I from 'immutable';
|
|
|
|
|
2019-04-28 23:45:03 -05:00
|
|
|
import {arrayUnique, compose, EventEmitter, flatten} from '@avocado/core';
|
2019-04-07 11:43:50 -05:00
|
|
|
import {Synchronized} from '@avocado/state';
|
2019-03-28 12:31:41 -05:00
|
|
|
|
|
|
|
import {Layer} from './layer';
|
2019-03-27 01:52:24 -05:00
|
|
|
|
|
|
|
const decorate = compose(
|
|
|
|
EventEmitter,
|
2019-04-16 17:52:56 -05:00
|
|
|
Synchronized,
|
2019-03-27 01:52:24 -05:00
|
|
|
);
|
|
|
|
|
2019-04-16 17:52:56 -05:00
|
|
|
export class Layers extends decorate(class {}) {
|
2019-03-27 01:52:24 -05:00
|
|
|
|
|
|
|
constructor() {
|
2019-03-27 16:18:27 -05:00
|
|
|
super();
|
2019-03-27 17:15:53 -05:00
|
|
|
this.layers = {};
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
*[Symbol.iterator]() {
|
2019-03-27 17:15:53 -05:00
|
|
|
for (const index in this.layers) {
|
|
|
|
const layer = this.layers[index];
|
|
|
|
yield {index, layer};
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
addEntityToLayer(entity, layerIndex) {
|
|
|
|
const layer = this.layers[layerIndex];
|
|
|
|
if (!layer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
layer.addEntity(entity);
|
|
|
|
}
|
|
|
|
|
2019-03-27 17:15:53 -05:00
|
|
|
addLayer(index, layer) {
|
2019-04-12 18:58:38 -05:00
|
|
|
layer.on('entityAdded', this.onEntityAddedToLayers, this);
|
|
|
|
layer.on('entityRemoved', this.onEntityRemovedFromLayers, this);
|
2019-03-27 17:15:53 -05:00
|
|
|
this.layers[index] = layer;
|
|
|
|
this.emit('layerAdded', layer, index);
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
|
2019-04-28 22:33:20 -05:00
|
|
|
allEntities() {
|
|
|
|
let allEntities = [];
|
|
|
|
for (const index in this.layers) {
|
|
|
|
const layer = this.layers[index];
|
|
|
|
allEntities = allEntities.concat(layer.allEntities());
|
|
|
|
}
|
|
|
|
return allEntities;
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
destroy() {
|
2019-03-27 17:15:53 -05:00
|
|
|
for (const index in this.layers) {
|
|
|
|
const layer = this.layers[index];
|
|
|
|
this.removeLayer(index);
|
2019-03-27 01:52:24 -05:00
|
|
|
layer.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 17:36:57 -05:00
|
|
|
findEntity(uuid) {
|
|
|
|
for (const index in this.layers) {
|
|
|
|
const layer = this.layers[index];
|
|
|
|
const foundEntity = layer.findEntity(uuid);
|
|
|
|
if (foundEntity) {
|
|
|
|
return foundEntity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
fromJSON(json) {
|
|
|
|
if (json) {
|
2019-03-27 17:15:53 -05:00
|
|
|
for (const index in json) {
|
|
|
|
const layerJSON = json[index];
|
2019-03-27 01:52:24 -05:00
|
|
|
const layer = new Layer()
|
2019-03-27 17:15:53 -05:00
|
|
|
this.addLayer(index, layer);
|
|
|
|
layer.fromJSON(layerJSON);
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2019-03-27 17:15:53 -05:00
|
|
|
layer(index) {
|
|
|
|
return this.layers[index];
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
onEntityAddedToLayers(entity) {
|
|
|
|
this.emit('entityAdded', entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
onEntityRemovedFromLayers(entity) {
|
|
|
|
this.emit('entityRemoved', entity);
|
|
|
|
}
|
|
|
|
|
2019-04-07 11:43:50 -05:00
|
|
|
patchStateStep(index, step) {
|
2019-04-06 23:19:32 -05:00
|
|
|
const layer = this.layers[index] ? this.layers[index] : new Layer();
|
|
|
|
if (!this.layers[index]) {
|
|
|
|
this.addLayer(index, layer);
|
|
|
|
}
|
|
|
|
layer.patchState([step]);
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
removeEntityFromLayer(entity, layerIndex) {
|
|
|
|
const layer = this.layers[layerIndex];
|
|
|
|
if (!layer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
layer.removeEntity(entity);
|
|
|
|
}
|
|
|
|
|
2019-03-27 17:15:53 -05:00
|
|
|
removeLayer(index) {
|
|
|
|
const layer = this.layers[index];
|
|
|
|
if (!layer) {
|
2019-03-27 01:52:24 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
layer.off('entityAdded', this.onEntityAddedToLayers);
|
|
|
|
layer.off('entityRemoved', this.onEntityRemovedFromLayers);
|
2019-03-27 17:15:53 -05:00
|
|
|
delete this.layers[index];
|
|
|
|
this.emit('layerRemoved', layer, index);
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
tick(elapsed) {
|
|
|
|
if (this.layers) {
|
2019-03-27 17:15:53 -05:00
|
|
|
for (const index in this.layers) {
|
|
|
|
const layer = this.layers[index];
|
2019-03-27 01:52:24 -05:00
|
|
|
layer.tick(elapsed);
|
|
|
|
}
|
2019-04-23 15:25:03 -05:00
|
|
|
if (AVOCADO_SERVER) {
|
|
|
|
this.state = this.state.withMutations((state) => {
|
|
|
|
for (const index in this.layers) {
|
|
|
|
const layer = this.layers[index];
|
|
|
|
state.set(index, layer.state);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-07 14:59:24 -05:00
|
|
|
visibleEntities(query) {
|
|
|
|
const layerEntities = [];
|
|
|
|
for (const {index, layer} of this) {
|
|
|
|
layerEntities.push(layer.visibleEntities(query));
|
|
|
|
}
|
|
|
|
return arrayUnique(flatten(layerEntities));
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|