refactor: entity informing elegance
This commit is contained in:
parent
750b74a6cd
commit
8ae661169c
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
Loading…
Reference in New Issue
Block a user