avocado-old/packages/topdown/layers.js
2019-05-13 21:07:51 -05:00

157 lines
3.8 KiB
JavaScript

import * as I from 'immutable';
import {arrayUnique, compose, EventEmitter, flatten} from '@avocado/core';
import {EntityCreatePacket} from '@avocado/entity';
import {Synchronized} from '@avocado/state';
import {Layer} from './layer';
import {LayerCreatePacket} from './packets/layer-create.packet';
import {TileUpdatePacket} from './packets/tile-update.packet';
const decorate = compose(
EventEmitter,
Synchronized,
);
export class Layers extends decorate(class {}) {
constructor(json) {
super();
this.layers = [];
if ('undefined' !== typeof json) {
this.fromJSON(json);
}
}
*[Symbol.iterator]() {
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);
}
}
addEntityToLayer(entity, layerIndex) {
const layer = this.layers[layerIndex];
if (!layer) {
return;
}
layer.addEntity(entity);
}
addLayer(layer) {
layer.on('entityAdded', this.onEntityAddedToLayers, this);
layer.on('entityRemoved', this.onEntityRemovedFromLayers, this);
this.layers.push(layer);
layer.index = this.layers.length - 1;
this.emit('layerAdded', layer);
}
allEntities() {
let allEntities = [];
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]);
}
}
return allEntities;
}
destroy() {
for (let i = 0; i < this.layers.length; i++) {
const layer = this.layers[i];
this.removeLayer(layer);
layer.destroy();
}
}
findEntity(uuid) {
for (let i = 0; i < this.layers.length; i++) {
const foundEntity = this.layers[i].findEntity(uuid);
if (foundEntity) {
return foundEntity;
}
}
}
fromJSON(json) {
for (let i = 0; i < json.length; i++) {
this.addLayer(new Layer(json[i]));
}
return this;
}
layer(index) {
return this.layers[index];
}
onEntityAddedToLayers(entity) {
this.emit('entityAdded', entity);
}
onEntityRemovedFromLayers(entity) {
this.emit('entityRemoved', entity);
}
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]);
}
}
return packets;
}
removeEntityFromLayer(entity, layerIndex) {
const layer = this.layers[layerIndex];
if (!layer) {
return;
}
layer.removeEntity(entity);
}
// TODO: fix index for remaining layers
removeLayer(layer) {
const index = this.layers.indexOf(layer);
if (-1 === index) {
return;
}
layer.off('entityAdded', this.onEntityAddedToLayers);
layer.off('entityRemoved', this.onEntityRemovedFromLayers);
this.layers.splice(index, 1);
this.emit('layerRemoved', layer);
}
tick(elapsed) {
for (let i = 0; i < this.layers.length; i++) {
this.layers[i].tick(elapsed);
}
}
visibleEntities(query) {
const entities = [];
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];
entities.push(layerVisibleEntity);
}
}
return entities;
}
}