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.removeAllTraits();
});
this.initializeSynchronizedChildren();
}
acceptPacket(packet) {

View File

@ -21,6 +21,7 @@ export class EntityList extends decorate(class {}) {
this._entities = {};
this._flatEntities = [];
this._quadTree = new QuadTree();
this.initializeSynchronizedChildren();
}
*[Symbol.iterator]() {
@ -117,10 +118,7 @@ export class EntityList extends decorate(class {}) {
this.tickAfterDestructionTickers(elapsed);
}
// Run normal tickers.
for (let i = 0; i < this._flatEntities.length; i++) {
const entity = this._flatEntities[i];
entity.tick(elapsed);
}
this.tickEntities(elapsed)
// Update state.
if (AVOCADO_SERVER) {
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) {
this.state = this.state.withMutations((state) => {
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.params = I.fromJS(ctor.defaultParams()).merge(I.fromJS(params));
this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state));
this.initializeSynchronizedChildren();
}
destroy() {}

View File

@ -14,6 +14,31 @@ export function Synchronized(Superclass) {
constructor(...args) {
super(...args);
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() {
@ -59,33 +84,39 @@ export function Synchronized(Superclass) {
}
tick(elapsed) {
const children = this.synchronizedChildren();
for (let i = 0; i < children.length; ++i) {
const key = children[i];
if (
'undefined' !== typeof this[key]
&& 'undefined' !== typeof this[key].tick
) {
this[key].tick(elapsed);
}
for (let i = 0; i < this._childrenWithTickers.length; i++) {
const key = this._childrenWithTickers[i];
this[key].tick(elapsed);
}
if (AVOCADO_SERVER) {
this.state = this.state.withMutations((state) => {
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]);
}
}
});
this.tickMutateState();
}
}
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.onTilesetUriChanged();
this.on('worldChanged', this.onWorldChanged, this);
this.initializeSynchronizedChildren();
}
addEntity(entity) {

View File

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

View File

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

View File

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