feat: optimize leaving/entering entities

This commit is contained in:
cha0s 2019-04-11 23:50:44 -05:00
parent 1a986987ae
commit 4755d78534

View File

@ -15,6 +15,7 @@ export class Informed extends decorate(Trait) {
initialize() {
this._packer = new Packer();
this._rememberedEntities = {};
this._socket = undefined;
this._state = I.Map();
}
@ -66,6 +67,85 @@ export class Informed extends decorate(Trait) {
const reducedState = this.reduceState(state);
// Take a pure JS diff.
const steps = immutablediff(this._state, reducedState).toJS();
// Rewrite entity removals.
const entityRemovals = steps.filter((step) => {
return 'remove' === step.op && step.path.match(
/\/room\/layers\/.*\/entityList\/[a-z0-9-]+/
);
});
for (const entityRemoval of entityRemovals) {
// Remember the entity.
const parts = entityRemoval.path.split('/');
parts.shift();
const uuid = parts[4];
this._rememberedEntities[uuid] = state.getIn(parts);
// Swap out the removal op for replaces to hide the entity.
const index = steps.indexOf(entityRemoval);
steps.splice(index, 1);
steps.push({
op: 'replace',
path: entityRemoval.path + '/existent/state/isTicking',
value: false,
});
steps.push({
op: 'replace',
path: entityRemoval.path + '/physical/state/addedToPhysics',
value: false,
});
steps.push({
op: 'replace',
path: entityRemoval.path + '/graphical/state/isVisible',
value: false,
});
}
// Rewrite entity adds.
const entityAdds = steps.filter((step) => {
return 'add' === step.op && step.path.match(
/\/room\/layers\/.*\/entityList\/[a-z0-9-]+/
);
});
for (const entityAdd of entityAdds) {
// Remember the entity.
const parts = entityAdd.path.split('/');
parts.shift();
const uuid = parts[4];
if (!(uuid in this._rememberedEntities)) {
continue;
}
const currentState = state.getIn(parts);
const addSteps = immutablediff(
this._rememberedEntities[uuid],
currentState,
).toJS();
const fullAddSteps = addSteps.map((addStep) => {
return {
op: addStep.op,
path: entityAdd.path + addStep.path,
value: addStep.value,
};
});
// Swap out the add op for replaces to show the entity.
const index = steps.indexOf(entityAdd);
steps.splice(index, 1);
steps.push(...fullAddSteps);
steps.push({
op: 'replace',
path: entityAdd.path + '/existent/state/isTicking',
value: true,
});
steps.push({
op: 'replace',
path: entityAdd.path + '/physical/state/addedToPhysics',
value: true,
});
steps.push({
op: 'replace',
path: entityAdd.path + '/graphical/state/isVisible',
value: true,
});
delete this._rememberedEntities[uuid];
}
// Remember state.
this._state = reducedState;
if (0 === steps.length) {
return;