perf: calculate synchronized children ahead of time

This commit is contained in:
cha0s 2019-05-03 23:12:50 -05:00
parent 4781c73753
commit 2eefd555bf
8 changed files with 69 additions and 27 deletions

View File

@ -68,6 +68,7 @@ export class Entity extends decorate(Resource) {
this.once('destroyed', () => { this.once('destroyed', () => {
this.removeAllTraits(); this.removeAllTraits();
}); });
this.initializeSynchronizedChildren();
} }
acceptPacket(packet) { acceptPacket(packet) {

View File

@ -21,6 +21,7 @@ export class EntityList extends decorate(class {}) {
this._entities = {}; this._entities = {};
this._flatEntities = []; this._flatEntities = [];
this._quadTree = new QuadTree(); this._quadTree = new QuadTree();
this.initializeSynchronizedChildren();
} }
*[Symbol.iterator]() { *[Symbol.iterator]() {
@ -117,10 +118,7 @@ export class EntityList extends decorate(class {}) {
this.tickAfterDestructionTickers(elapsed); this.tickAfterDestructionTickers(elapsed);
} }
// Run normal tickers. // Run normal tickers.
for (let i = 0; i < this._flatEntities.length; i++) { this.tickEntities(elapsed)
const entity = this._flatEntities[i];
entity.tick(elapsed);
}
// Update state. // Update state.
if (AVOCADO_SERVER) { if (AVOCADO_SERVER) {
this.tickMutateState(); this.tickMutateState();
@ -142,6 +140,13 @@ export class EntityList extends decorate(class {}) {
} }
} }
tickEntities(elapsed) {
for (let i = 0; i < this._flatEntities.length; i++) {
const entity = this._flatEntities[i];
entity.tick(elapsed);
}
}
tickMutateState(state) { tickMutateState(state) {
this.state = this.state.withMutations((state) => { this.state = this.state.withMutations((state) => {
for (let i = 0; i < this._dirtyEntities.length; i++) { for (let i = 0; i < this._dirtyEntities.length; i++) {

View File

@ -19,6 +19,7 @@ export class Trait extends decorate(class {}) {
this._memoizedListeners = undefined; this._memoizedListeners = undefined;
this.params = I.fromJS(ctor.defaultParams()).merge(I.fromJS(params)); this.params = I.fromJS(ctor.defaultParams()).merge(I.fromJS(params));
this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state)); this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state));
this.initializeSynchronizedChildren();
} }
destroy() {} destroy() {}

View File

@ -14,6 +14,31 @@ export function Synchronized(Superclass) {
constructor(...args) { constructor(...args) {
super(...args); super(...args);
this.state = I.Map(); this.state = I.Map();
this._childrenWithState = []
this._childrenWithoutState = [];
this._childrenWithTickers = [];
}
initializeSynchronizedChildren() {
const synchronizedChildren = this.synchronizedChildren();
for (let i = 0; i < synchronizedChildren.length; ++i) {
const key = synchronizedChildren[i];
if (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].tick
) {
this._childrenWithTickers.push(key);
}
if (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].state
) {
this._childrenWithState.push(key);
}
else {
this._childrenWithoutState.push(key);
}
}
} }
synchronizedChildren() { synchronizedChildren() {
@ -59,33 +84,39 @@ export function Synchronized(Superclass) {
} }
tick(elapsed) { tick(elapsed) {
const children = this.synchronizedChildren(); for (let i = 0; i < this._childrenWithTickers.length; i++) {
for (let i = 0; i < children.length; ++i) { const key = this._childrenWithTickers[i];
const key = children[i]; this[key].tick(elapsed);
if (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].tick
) {
this[key].tick(elapsed);
}
} }
if (AVOCADO_SERVER) { if (AVOCADO_SERVER) {
this.state = this.state.withMutations((state) => { this.tickMutateState();
for (let i = 0; i < children.length; ++i) {
const key = children[i];
if (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].state
) {
state.set(key, this[key].state);
}
else {
state.set(key, this[key]);
}
}
});
} }
} }
prepareStateMutation() {
const mutation = {};
for (let i = 0; i < this._childrenWithState.length; i++) {
const key = this._childrenWithState[i];
mutation[key] = this[key].state;
}
for (let i = 0; i < this._childrenWithoutState.length; i++) {
const key = this._childrenWithoutState[i];
mutation[key] = this[key];
}
}
tickMutateState() {
this.state = this.state.withMutations((state) => {
for (let i = 0; i < this._childrenWithState.length; i++) {
const key = this._childrenWithState[i];
state.set(key, this[key].state);
}
for (let i = 0; i < this._childrenWithoutState.length; i++) {
const key = this._childrenWithoutState[i];
state.set(key, this[key]);
}
});
}
} }
} }

View File

@ -38,6 +38,7 @@ export class Layer extends decorate(class {}) {
this.on('tilesetUriChanged', this.onTilesetUriChanged, this); this.on('tilesetUriChanged', this.onTilesetUriChanged, this);
this.onTilesetUriChanged(); this.onTilesetUriChanged();
this.on('worldChanged', this.onWorldChanged, this); this.on('worldChanged', this.onWorldChanged, this);
this.initializeSynchronizedChildren();
} }
addEntity(entity) { addEntity(entity) {

View File

@ -15,6 +15,7 @@ export class Layers extends decorate(class {}) {
constructor() { constructor() {
super(); super();
this.layers = {}; this.layers = {};
this.initializeSynchronizedChildren();
} }
*[Symbol.iterator]() { *[Symbol.iterator]() {

View File

@ -34,6 +34,7 @@ export class Room extends decorate(class {}) {
this.layers.on('layerAdded', this.onLayerAdded, this); this.layers.on('layerAdded', this.onLayerAdded, this);
this.on('sizeChanged', this.onSizeChanged, this); this.on('sizeChanged', this.onSizeChanged, this);
this.on('worldChanged', this.onWorldChanged, this); this.on('worldChanged', this.onWorldChanged, this);
this.initializeSynchronizedChildren();
} }
addEntityToLayer(entity, layerIndex = 0) { addEntityToLayer(entity, layerIndex = 0) {

View File

@ -17,6 +17,7 @@ export class Tiles extends decorate(class {}) {
constructor() { constructor() {
super(); super();
this.data = I.List(); this.data = I.List();
this.initializeSynchronizedChildren();
} }
forEachTile(fn) { forEachTile(fn) {