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