avocado-old/packages/topdown/layer.js
2019-04-12 18:49:07 -05:00

122 lines
2.9 KiB
JavaScript

import * as I from 'immutable';
import {compose} from '@avocado/core';
import {create as createEntity, EntityList} from '@avocado/entity';
import {EventEmitter, Property} from '@avocado/mixins';
import {Synchronized} from '@avocado/state';
import {Tiles} from './tiles';
import {Tileset} from './tileset';
const decorate = compose(
EventEmitter,
Property('tilesetUri', {
track: true,
}),
Property('tileset', {
track: true,
}),
);
export class Layer extends decorate(Synchronized) {
constructor() {
super();
this.entityList = new EntityList();
this.tiles = new Tiles();
// Listeners.
this.onEntityAddedToLayer = this.onEntityAddedToLayer.bind(this);
this.onEntityRemovedFromLayer = this.onEntityRemovedFromLayer.bind(this);
this.entityList.on('entityAdded', this.onEntityAddedToLayer);
this.entityList.on('entityRemoved', this.onEntityRemovedFromLayer);
this.onTileDataChanged = this.onTileDataChanged.bind(this);
this.tiles.on('dataChanged', this.onTileDataChanged);
// Watch tileset URI change.
this.onTilesetUriChanged = this.onTilesetUriChanged.bind(this);
this.on('tilesetUriChanged', this.onTilesetUriChanged);
this.onTilesetUriChanged();
}
addEntity(entity) {
this.entityList.addEntity(entity);
}
destroy() {
this.entityList.destroy();
this.entityList.off('entityAdded', this.onEntityAddedToLayer);
this.entityList.off('entityRemoved', this.onEntityRemovedFromLayer);
this.tiles.off('dataChanged', this.onTileDataChanged);
this.off('tilesetUriChanged', this.onTilesetUriChanged);
if (this.tileset) {
this.tileset.destroy();
}
}
findEntity(uuid) {
return this.entityList.findEntity(uuid);
}
fromJSON(json) {
if (json.entities) {
json.entities.forEach((entityJSON) => {
const entity = createEntity();
this.entityList.addEntity(entity.fromJSON(entityJSON));
});
}
if (json.tiles) {
this.tiles.fromJSON(json.tiles)
}
if (json.tilesetUri) {
this.tilesetUri = json.tilesetUri;
}
return this;
}
onEntityAddedToLayer(entity) {
entity.addTrait('layered');
entity.layer = this;
this.emit('entityAdded', entity)
}
onEntityRemovedFromLayer(entity) {
if (entity.is('layered')) {
entity.removeTrait('layered');
}
this.emit('entityRemoved', entity);
}
onTileDataChanged() {
this.emit('tileDataChanged');
}
onTilesetUriChanged() {
if (!this.tilesetUri) {
return;
}
Tileset.load(this.tilesetUri).then((tileset) => {
this.tileset = tileset;
});
}
removeEntity(entity) {
this.entityList.removeEntity(entity);
}
setTileAt(x, y, tile) {
this.tiles.setTileAt(x, y, tile);
}
synchronizedChildren() {
return [
'entityList',
'tiles',
'tilesetUri',
];
}
visibleEntities(query) {
return this.entityList.visibleEntities(query);
}
}