humus-old/traits/informed.js

113 lines
2.4 KiB
JavaScript
Raw Normal View History

2019-03-20 18:35:59 -05:00
import * as I from 'immutable';
2019-03-20 18:58:19 -05:00
import {compose} from '@avocado/core';
2019-03-23 23:24:31 -05:00
import {StateProperty, Trait} from '@avocado/entity';
2019-03-20 18:35:59 -05:00
2019-03-20 18:58:19 -05:00
const decorate = compose(
2019-03-23 23:24:31 -05:00
StateProperty('informSize'),
2019-03-20 18:58:19 -05:00
);
class InformedBase extends Trait {
static defaultState() {
return {
2019-03-25 18:57:28 -05:00
informSize: [640, 360],
2019-03-20 18:58:19 -05:00
};
}
2019-03-20 18:35:59 -05:00
initialize() {
this._sentSelf = false;
this._socket = undefined;
2019-03-20 18:35:59 -05:00
this.lastNearby = I.Set();
}
2019-03-20 23:22:54 -05:00
destroy() {
2019-03-21 01:32:59 -05:00
if (this._socket) {
delete this._socket.entity;
delete this._socket;
}
2019-03-20 23:22:54 -05:00
}
2019-03-21 01:14:39 -05:00
reduceStateDiffForEntityList(diff, position) {
2019-03-23 20:06:06 -05:00
// Only if entity list exists.
if (!diff.entityList) {
return diff;
}
2019-03-20 18:58:19 -05:00
// Reduce the entity list.
2019-03-21 01:14:39 -05:00
const informSize = this.entity.informSize.toJS();
const nearbyEntities = this.entity.nearbyEntities(informSize, position);
2019-03-20 18:58:19 -05:00
const reducedEntityList = {};
let nearby = I.Set();
for (const entity of nearbyEntities) {
nearby = nearby.add(entity);
const uuid = entity.instanceUuid;
if (this.lastNearby.has(entity)) {
// Keep diff.
if (diff.entityList[uuid]) {
reducedEntityList[uuid] = diff.entityList[uuid];
}
}
else {
// Added.
reducedEntityList[uuid] = entity.state().toJS();
}
}
for (const entity of this.lastNearby.values()) {
const uuid = entity.instanceUuid;
if (!nearby.has(entity)) {
// Removed.
reducedEntityList[uuid] = false;
}
}
// Track who's nearby.
this.lastNearby = nearby;
// Merge the reduction.
diff = {
...diff,
entityList: reducedEntityList,
};
// Remove dead update.
if (0 === Object.keys(diff.entityList).length) {
delete diff.entityList;
}
return diff;
}
get socket() {
return this._socket;
}
set socket(socket) {
socket.entity = this.entity;
this._socket = socket;
}
2019-03-20 18:35:59 -05:00
methods() {
return {
inform: (diff) => {
2019-03-20 18:58:19 -05:00
// Remove dead updates.
if (0 === Object.keys(diff).length) {
return;
}
if (!this._sentSelf) {
2019-03-21 18:33:29 -05:00
diff.selfEntity = this.entity.instanceUuid;
this._sentSelf = true;
}
2019-03-20 18:35:59 -05:00
this._socket.send({
type: 'state-update',
payload: diff,
});
},
2019-03-21 01:14:39 -05:00
reduceStateDiff: (diff, position) => {
return this.reduceStateDiffForEntityList(diff, position);
2019-03-20 18:35:59 -05:00
},
};
}
}
2019-03-20 18:58:19 -05:00
export class Informed extends decorate(InformedBase) {}