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-05-13 21:07:51 -05:00
|
|
|
import {EntityCreatePacket} from '@avocado/entity';
|
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-05-13 21:07:51 -05:00
|
|
|
import {LayerCreatePacket} from './packets/layer-create.packet';
|
|
|
|
import {TileUpdatePacket} from './packets/tile-update.packet';
|
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
|
|
|
|
2019-05-13 21:07:51 -05:00
|
|
|
constructor(json) {
|
2019-03-27 16:18:27 -05:00
|
|
|
super();
|
2019-05-13 21:07:51 -05:00
|
|
|
this.layers = [];
|
|
|
|
if ('undefined' !== typeof json) {
|
|
|
|
this.fromJSON(json);
|
|
|
|
}
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
*[Symbol.iterator]() {
|
2019-05-13 21:07:51 -05:00
|
|
|
for (let i = 0; i < this.layers.length; i++) {
|
|
|
|
yield this.layers[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
acceptPacket(packet) {
|
|
|
|
if (packet instanceof LayerCreatePacket) {
|
|
|
|
this.addLayer(new Layer(packet.data));
|
|
|
|
}
|
|
|
|
if (packet instanceof TileUpdatePacket) {
|
|
|
|
this.layers[packet.data.layer].acceptPacket(packet);
|
|
|
|
}
|
|
|
|
if (packet instanceof EntityCreatePacket) {
|
|
|
|
this.layers[packet.data.layer].acceptPacket(packet);
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
addEntityToLayer(entity, layerIndex) {
|
|
|
|
const layer = this.layers[layerIndex];
|
|
|
|
if (!layer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
layer.addEntity(entity);
|
|
|
|
}
|
|
|
|
|
2019-05-13 21:07:51 -05:00
|
|
|
addLayer(layer) {
|
2019-04-12 18:58:38 -05:00
|
|
|
layer.on('entityAdded', this.onEntityAddedToLayers, this);
|
|
|
|
layer.on('entityRemoved', this.onEntityRemovedFromLayers, this);
|
2019-05-13 21:07:51 -05:00
|
|
|
this.layers.push(layer);
|
|
|
|
layer.index = this.layers.length - 1;
|
|
|
|
this.emit('layerAdded', layer);
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
|
2019-04-28 22:33:20 -05:00
|
|
|
allEntities() {
|
|
|
|
let allEntities = [];
|
2019-05-13 21:07:51 -05:00
|
|
|
for (let i = 0; i < this.layers.length; i++) {
|
|
|
|
const layerEntities = this.layers[i].allEntities();
|
|
|
|
for (let j = 0; j < layerEntities.length; j++) {
|
|
|
|
allEntities.push(layerEntities[j]);
|
|
|
|
}
|
2019-04-28 22:33:20 -05:00
|
|
|
}
|
|
|
|
return allEntities;
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
destroy() {
|
2019-05-13 21:07:51 -05:00
|
|
|
for (let i = 0; i < this.layers.length; i++) {
|
|
|
|
const layer = this.layers[i];
|
|
|
|
this.removeLayer(layer);
|
2019-03-27 01:52:24 -05:00
|
|
|
layer.destroy();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 17:36:57 -05:00
|
|
|
findEntity(uuid) {
|
2019-05-13 21:07:51 -05:00
|
|
|
for (let i = 0; i < this.layers.length; i++) {
|
|
|
|
const foundEntity = this.layers[i].findEntity(uuid);
|
2019-03-27 17:36:57 -05:00
|
|
|
if (foundEntity) {
|
|
|
|
return foundEntity;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
fromJSON(json) {
|
2019-05-13 21:07:51 -05:00
|
|
|
for (let i = 0; i < json.length; i++) {
|
|
|
|
this.addLayer(new Layer(json[i]));
|
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-05-13 21:07:51 -05:00
|
|
|
packetsForUpdate(force = false) {
|
|
|
|
const packets = [];
|
|
|
|
for (let i = 0; i < this.layers.length; i++) {
|
|
|
|
const layerPacketsForUpdate = this.layers[i].packetsForUpdate(force);
|
|
|
|
for (let j = 0; j < layerPacketsForUpdate.length; j++) {
|
|
|
|
packets.push(layerPacketsForUpdate[j]);
|
|
|
|
}
|
2019-04-06 23:19:32 -05:00
|
|
|
}
|
2019-05-13 21:07:51 -05:00
|
|
|
return packets;
|
2019-04-06 23:19:32 -05:00
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
removeEntityFromLayer(entity, layerIndex) {
|
|
|
|
const layer = this.layers[layerIndex];
|
|
|
|
if (!layer) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
layer.removeEntity(entity);
|
|
|
|
}
|
|
|
|
|
2019-05-13 21:07:51 -05:00
|
|
|
// TODO: fix index for remaining layers
|
|
|
|
removeLayer(layer) {
|
|
|
|
const index = this.layers.indexOf(layer);
|
|
|
|
if (-1 === index) {
|
2019-03-27 01:52:24 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
layer.off('entityAdded', this.onEntityAddedToLayers);
|
|
|
|
layer.off('entityRemoved', this.onEntityRemovedFromLayers);
|
2019-05-13 21:07:51 -05:00
|
|
|
this.layers.splice(index, 1);
|
|
|
|
this.emit('layerRemoved', layer);
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
tick(elapsed) {
|
2019-05-13 21:07:51 -05:00
|
|
|
for (let i = 0; i < this.layers.length; i++) {
|
|
|
|
this.layers[i].tick(elapsed);
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-07 14:59:24 -05:00
|
|
|
visibleEntities(query) {
|
2019-05-04 11:39:03 -05:00
|
|
|
const entities = [];
|
2019-05-13 21:07:51 -05:00
|
|
|
for (let i = 0; i < this.layers.length; i++) {
|
|
|
|
const layerVisibleEntities = this.layers[i].visibleEntities(query);
|
|
|
|
for (let j = 0; j < layerVisibleEntities.length; j++) {
|
|
|
|
const layerVisibleEntity = layerVisibleEntities[j];
|
2019-05-04 11:39:03 -05:00
|
|
|
entities.push(layerVisibleEntity);
|
|
|
|
}
|
2019-04-07 14:59:24 -05:00
|
|
|
}
|
2019-05-04 11:39:03 -05:00
|
|
|
return entities;
|
2019-04-07 14:59:24 -05:00
|
|
|
}
|
|
|
|
|
2019-03-27 01:52:24 -05:00
|
|
|
}
|