refactor: entity informing elegance

This commit is contained in:
cha0s 2019-03-20 18:58:19 -05:00
parent 750b74a6cd
commit 8ae661169c
2 changed files with 70 additions and 54 deletions

View File

@ -14,8 +14,6 @@ import {Controllable} from './traits/controllable';
registerTrait(Controllable);
import {Informed} from './traits/informed';
registerTrait(Informed);
// Define range for entity updates.
const INFORM_SIZE = [200, 200];
// Create game.
export default function(avocadoServer) {
avocadoServer.on('connect', createConnectionListener(avocadoServer));
@ -40,12 +38,8 @@ function createConnectionListener(avocadoServer) {
socket.entity = entity;
// Send current state.
const currentState = stateSynchronizer.state().toJS();
const nearbyEntities = entity.nearbyEntities(INFORM_SIZE);
const reduced = entity.reduceStateDiff(nearbyEntities, currentState);
// Remove dead update.
if (0 !== Object.keys(reduced).length) {
entity.inform(reduced);
}
const reduced = entity.reduceStateDiff(currentState);
entity.inform(reduced);
// Listen for events.
socket.on('message', createMessageListener(avocadoServer, socket));
socket.on('disconnect', createDisconnectionListener(avocadoServer, socket));
@ -66,7 +60,7 @@ function createMessageListener(avocadoServer, socket) {
function createDisconnectionListener(avocadoServer, socket) {
const {entity} = socket;
return () => {
const nearbyEntities = entity.nearbyEntities(INFORM_SIZE);
const nearbyEntities = entity.entitiesToInform();
entityList.removeEntity(entity);
nearbyEntities.forEach((nearbyEntity) => {
nearbyEntity.inform({
@ -135,12 +129,8 @@ function createMainLoop(avocadoServer) {
if (!('inform' in entity)) {
continue;
}
const nearbyEntities = entity.nearbyEntities(INFORM_SIZE);
const reduced = entity.reduceStateDiff(nearbyEntities, diff);
// Remove dead update.
if (0 !== Object.keys(reduced).length) {
entity.inform(reduced);
}
const reduced = entity.reduceStateDiff(diff);
entity.inform(reduced);
}
}
}

View File

@ -1,8 +1,19 @@
import * as I from 'immutable';
import {Trait} from '@avocado/entity';
import {compose} from '@avocado/core';
import {simpleState, Trait} from '@avocado/entity';
export class Informed extends Trait {
const decorate = compose(
simpleState('informSize'),
);
class InformedBase extends Trait {
static defaultState() {
return {
informSize: [300, 300],
};
}
initialize() {
this._socket = this.params.get('socket');
@ -10,53 +21,67 @@ export class Informed extends Trait {
this.lastNearby = I.Set();
}
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;
}
methods() {
return {
entitiesToInform: () => {
const informSize = this.entity.informSize.toJS();
return this.entity.nearbyEntities(informSize);
},
inform: (diff) => {
// Remove dead updates.
if (0 === Object.keys(diff).length) {
return;
}
this._socket.send({
type: 'state-update',
payload: diff,
});
},
reduceStateDiff: (nearbyEntities, diff) => {
// Reduce the entity list.
const reducedEntityListDiff = {};
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]) {
reducedEntityListDiff[uuid] = diff.entityList[uuid];
}
}
else {
// Added.
reducedEntityListDiff[uuid] = entity.state().toJS();
}
}
for (const entity of this.lastNearby.values()) {
const uuid = entity.instanceUuid;
if (!nearby.has(entity)) {
// Removed.
reducedEntityListDiff[uuid] = false;
}
}
// Track who's nearby.
this.lastNearby = nearby;
// Merge the reduction.
diff = {
...diff,
entityList: reducedEntityListDiff,
};
// Remove dead update.
if (0 === Object.keys(diff.entityList).length) {
delete diff.entityList;
}
return diff;
reduceStateDiff: (diff) => {
return this.reduceStateDiffForEntityList(diff);
},
};
@ -64,3 +89,4 @@ export class Informed extends Trait {
}
export class Informed extends decorate(InformedBase) {}