avocado-old/packages/entity/list.js

125 lines
3.1 KiB
JavaScript
Raw Normal View History

2019-03-17 23:45:48 -05:00
import * as I from 'immutable';
import mapValues from 'lodash.mapvalues';
import {compose} from '@avocado/core';
2019-03-20 18:35:19 -05:00
import {QuadTree} from '@avocado/math';
import {EventEmitter} from '@avocado/mixins';
2019-03-17 23:45:48 -05:00
import {create} from './index';
const decorate = compose(
EventEmitter,
);
class EntityListBase {
2019-03-17 23:45:48 -05:00
constructor() {
this.entities_PRIVATE = {};
2019-03-20 18:35:19 -05:00
this.quadTree_PRIVATE = new QuadTree();
this.quadTreeData_PRIVATE = {};
2019-03-17 23:45:48 -05:00
this.state_PRIVATE = I.Map();
this.uuidMap_PRIVATE = {};
}
*[Symbol.iterator]() {
for (const uuid in this.entities_PRIVATE) {
const entity = this.entities_PRIVATE[uuid];
yield entity;
}
}
acceptStateChange(change) {
for (const uuid in change) {
const localUuid = this.uuidMap_PRIVATE[uuid];
const entity = this.entities_PRIVATE[localUuid];
if (entity) {
if (false === change[uuid]) {
// Entity removed.
this.removeEntity(entity);
}
else {
entity.acceptStateChange(change[uuid]);
this.state_PRIVATE = this.state_PRIVATE.set(localUuid, entity.state());
}
}
else {
2019-03-18 21:22:54 -05:00
// New entity. Create with change as traits.
const newEntity = create().fromJSON({
traits: change[uuid],
});
2019-03-17 23:45:48 -05:00
this.addEntity(newEntity);
this.uuidMap_PRIVATE[uuid] = newEntity.instanceUuid;
}
}
}
addEntity(entity) {
const uuid = entity.instanceUuid;
this.entities_PRIVATE[uuid] = entity;
this.state_PRIVATE = this.state_PRIVATE.set(uuid, entity.state());
entity.on('destroyed', () => {
this.removeEntity(entity);
});
2019-03-20 18:35:19 -05:00
entity.on('positionChanged', () => {
this.quadTree_PRIVATE.remove(this.quadTreePoint(entity));
this.quadTree_PRIVATE.add(this.recomputeQuadTreePoint(entity));
});
this.emit('entityAdded', entity);
2019-03-20 18:35:19 -05:00
this.quadTree_PRIVATE.add(this.recomputeQuadTreePoint(entity));
2019-03-17 23:45:48 -05:00
}
entity(uuid) {
return this.entities_PRIVATE[uuid];
}
2019-03-20 18:35:19 -05:00
quadTreePoint(entity) {
return this.quadTreeData_PRIVATE[entity.instanceUuid];
}
recomputeQuadTreePoint(entity) {
const point = this.quadTreeData_PRIVATE[entity.instanceUuid] = [
entity.x,
entity.y,
entity,
];
return point;
}
2019-03-17 23:45:48 -05:00
recomputeState() {
for (const uuid in this.entities_PRIVATE) {
const entity = this.entities_PRIVATE[uuid];
this.state_PRIVATE = this.state_PRIVATE.set(uuid, entity.state());
}
}
removeEntity(entity) {
const uuid = entity.instanceUuid;
delete this.entities_PRIVATE[uuid];
this.state_PRIVATE = this.state_PRIVATE.delete(uuid);
this.emit('entityRemoved', entity);
2019-03-17 23:45:48 -05:00
}
state() {
return this.state_PRIVATE;
}
tick(elapsed) {
for (const uuid in this.entities_PRIVATE) {
const entity = this.entities_PRIVATE[uuid];
if ('tick' in entity) {
entity.tick(elapsed);
}
}
this.recomputeState();
}
2019-03-20 18:35:19 -05:00
within(rectangle) {
return this.quadTree_PRIVATE.search(rectangle).map((node) => {
return node.data[2];
});
}
2019-03-17 23:45:48 -05:00
}
export class EntityList extends decorate(EntityListBase) {}