perf: list ticking/dirty optimization
This commit is contained in:
parent
9317c69c57
commit
9909b12c41
|
@ -278,6 +278,9 @@ export class Entity extends decorate(Resource) {
|
|||
}
|
||||
instance.isDirty = false;
|
||||
this.isDirty = true;
|
||||
if (this.is('listed')) {
|
||||
this.list.markEntityDirty(this);
|
||||
}
|
||||
this._setInstanceState(state, type, instance);
|
||||
}
|
||||
});
|
||||
|
|
|
@ -17,7 +17,9 @@ export class EntityList extends decorate(class {}) {
|
|||
constructor() {
|
||||
super();
|
||||
this._afterDestructionTickers = [];
|
||||
this._dirtyEntities = [];
|
||||
this._entities = {};
|
||||
this._flatEntities = [];
|
||||
this._quadTree = new QuadTree();
|
||||
}
|
||||
|
||||
|
@ -31,15 +33,19 @@ export class EntityList extends decorate(class {}) {
|
|||
addEntity(entity) {
|
||||
const uuid = entity.instanceUuid;
|
||||
this._entities[uuid] = entity;
|
||||
this._flatEntities.push(entity);
|
||||
this.state = this.state.set(uuid, entity.state);
|
||||
entity.addTrait('listed');
|
||||
entity.list = this;
|
||||
entity.setIntoList(this);
|
||||
entity.once('destroy', () => {
|
||||
this.removeEntity(entity);
|
||||
// In the process of destroying, allow entities to specify tickers that
|
||||
// must live on past destruction.
|
||||
const tickers = entity.invokeHookFlat('afterDestructionTickers');
|
||||
this._afterDestructionTickers.push(...tickers);
|
||||
for (let i = 0; i < tickers.length; i++) {
|
||||
const ticker = tickers[i];
|
||||
this._afterDestructionTickers.push(ticker);
|
||||
}
|
||||
});
|
||||
this.emit('entityAdded', entity);
|
||||
}
|
||||
|
@ -51,11 +57,17 @@ export class EntityList extends decorate(class {}) {
|
|||
}
|
||||
|
||||
findEntity(uuid) {
|
||||
if (this._entities[uuid]) {
|
||||
if (uuid in this._entities) {
|
||||
return this._entities[uuid];
|
||||
}
|
||||
}
|
||||
|
||||
markEntityDirty(entity) {
|
||||
if (-1 === this._dirtyEntities.indexOf(entity)) {
|
||||
this._dirtyEntities.push(entity);
|
||||
}
|
||||
}
|
||||
|
||||
patchStateStep(uuid, step) {
|
||||
const entity = this._entities[uuid];
|
||||
if ('/' === step.path) {
|
||||
|
@ -90,6 +102,8 @@ export class EntityList extends decorate(class {}) {
|
|||
removeEntity(entity) {
|
||||
const uuid = entity.instanceUuid;
|
||||
delete this._entities[uuid];
|
||||
const index = this._flatEntities.indexOf(entity);
|
||||
this._flatEntities.splice(index, 1);
|
||||
this.state = this.state.delete(uuid);
|
||||
this.emit('entityRemoved', entity);
|
||||
if (entity.is('listed')) {
|
||||
|
@ -99,24 +113,17 @@ export class EntityList extends decorate(class {}) {
|
|||
|
||||
tick(elapsed) {
|
||||
// Run after destruction tickers.
|
||||
if (this._afterDestructionTickers.length > 0) {
|
||||
this.tickAfterDestructionTickers(elapsed);
|
||||
}
|
||||
// Run normal tickers.
|
||||
for (const uuid in this._entities) {
|
||||
const entity = this._entities[uuid];
|
||||
for (let i = 0; i < this._flatEntities.length; i++) {
|
||||
const entity = this._flatEntities[i];
|
||||
entity.tick(elapsed);
|
||||
}
|
||||
// Update state.
|
||||
if (AVOCADO_SERVER) {
|
||||
this.state = this.state.withMutations((state) => {
|
||||
for (const uuid in this._entities) {
|
||||
const entity = this._entities[uuid];
|
||||
if (!entity.isDirty) {
|
||||
continue;
|
||||
}
|
||||
entity.isDirty = false;
|
||||
state.set(uuid, entity.state);
|
||||
}
|
||||
});
|
||||
this.tickMutateState();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,6 +142,17 @@ export class EntityList extends decorate(class {}) {
|
|||
}
|
||||
}
|
||||
|
||||
tickMutateState(state) {
|
||||
this.state = this.state.withMutations((state) => {
|
||||
for (let i = 0; i < this._dirtyEntities.length; i++) {
|
||||
const entity = this._dirtyEntities[i];
|
||||
entity.isDirty = false;
|
||||
state.set(entity.$$avocado_property_instanceUuid, entity.state);
|
||||
}
|
||||
});
|
||||
this._dirtyEntities = [];
|
||||
}
|
||||
|
||||
visibleEntities(query) {
|
||||
const entities = [];
|
||||
const entitiesTrack = [];
|
||||
|
|
|
@ -5,29 +5,19 @@ import {Trait} from '../trait';
|
|||
export class Listed extends Trait {
|
||||
|
||||
initialize() {
|
||||
this._list = undefined;
|
||||
this.entity.list = undefined;
|
||||
this.quadTreeAabb = [];
|
||||
this.quadTreeNodes = [];
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.removeQuadTreeNodes();
|
||||
delete this._list;
|
||||
delete this.entity.list;
|
||||
this.entity.emit('removedFromList');
|
||||
}
|
||||
|
||||
get list() {
|
||||
return this._list;
|
||||
}
|
||||
|
||||
set list(list) {
|
||||
this._list = list;
|
||||
this.addQuadTreeNodes();
|
||||
this.entity.emit('addedToList');
|
||||
}
|
||||
|
||||
addQuadTreeNodes() {
|
||||
const list = this._list;
|
||||
const list = this.entity.list;
|
||||
if (!list) {
|
||||
return;
|
||||
}
|
||||
|
@ -54,7 +44,7 @@ export class Listed extends Trait {
|
|||
}
|
||||
|
||||
removeQuadTreeNodes() {
|
||||
const list = this._list;
|
||||
const list = this.entity.list;
|
||||
if (!list) {
|
||||
return;
|
||||
}
|
||||
|
@ -97,5 +87,17 @@ export class Listed extends Trait {
|
|||
}
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
setIntoList: (list) => {
|
||||
this.entity.list = list;
|
||||
this.addQuadTreeNodes();
|
||||
this.entity.emit('addedToList');
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user