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';
|
|
|
|
import {simpleState, Trait} from '@avocado/entity';
|
2019-03-20 18:35:59 -05:00
|
|
|
|
2019-03-20 18:58:19 -05:00
|
|
|
const decorate = compose(
|
|
|
|
simpleState('informSize'),
|
|
|
|
);
|
|
|
|
|
|
|
|
class InformedBase extends Trait {
|
|
|
|
|
|
|
|
static defaultState() {
|
|
|
|
return {
|
2019-03-20 19:31:18 -05:00
|
|
|
informSize: [1280, 720],
|
2019-03-20 18:58:19 -05:00
|
|
|
};
|
|
|
|
}
|
2019-03-20 18:35:59 -05:00
|
|
|
|
|
|
|
initialize() {
|
2019-03-21 00:25:56 -05:00
|
|
|
this._sentSelf = false;
|
2019-03-20 23:01:48 -05:00
|
|
|
this._socket = undefined;
|
2019-03-20 18:35:59 -05:00
|
|
|
this.lastNearby = I.Set();
|
|
|
|
}
|
|
|
|
|
2019-03-20 23:22:54 -05:00
|
|
|
destroy() {
|
|
|
|
delete this._socket.entity;
|
|
|
|
delete this._socket;
|
|
|
|
}
|
|
|
|
|
2019-03-20 18:58:19 -05:00
|
|
|
reduceStateDiffForEntityList(diff) {
|
|
|
|
// Reduce the entity list.
|
|
|
|
const nearbyEntities = this.entity.entitiesToInform();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2019-03-20 23:01:48 -05:00
|
|
|
get socket() {
|
|
|
|
return this._socket;
|
|
|
|
}
|
|
|
|
|
|
|
|
set socket(socket) {
|
2019-03-21 00:29:44 -05:00
|
|
|
socket.entity = this.entity;
|
2019-03-20 23:01:48 -05:00
|
|
|
this._socket = socket;
|
|
|
|
}
|
|
|
|
|
2019-03-20 18:35:59 -05:00
|
|
|
methods() {
|
|
|
|
return {
|
|
|
|
|
2019-03-20 18:58:19 -05:00
|
|
|
entitiesToInform: () => {
|
|
|
|
const informSize = this.entity.informSize.toJS();
|
|
|
|
return this.entity.nearbyEntities(informSize);
|
|
|
|
},
|
|
|
|
|
2019-03-20 18:35:59 -05:00
|
|
|
inform: (diff) => {
|
2019-03-20 18:58:19 -05:00
|
|
|
// Remove dead updates.
|
|
|
|
if (0 === Object.keys(diff).length) {
|
|
|
|
return;
|
|
|
|
}
|
2019-03-21 00:25:56 -05:00
|
|
|
if (!this._sentSelf) {
|
|
|
|
diff.selfEntity = this.entity;
|
|
|
|
this._sentSelf = true;
|
|
|
|
}
|
2019-03-20 18:35:59 -05:00
|
|
|
this._socket.send({
|
|
|
|
type: 'state-update',
|
|
|
|
payload: diff,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
|
2019-03-20 18:58:19 -05:00
|
|
|
reduceStateDiff: (diff) => {
|
|
|
|
return this.reduceStateDiffForEntityList(diff);
|
2019-03-20 18:35:59 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-03-20 18:58:19 -05:00
|
|
|
export class Informed extends decorate(InformedBase) {}
|