perf: faster props and auto sync children init

This commit is contained in:
cha0s 2019-05-08 23:54:30 -05:00
parent fa07451cd2
commit 3e4f48c517
10 changed files with 23 additions and 15 deletions

View File

@ -94,12 +94,15 @@ export class Entity extends decorate(Resource) {
this.once('destroyed', () => { this.once('destroyed', () => {
this.removeAllTraits(); this.removeAllTraits();
}); });
this.initializeSynchronizedChildren(); // Bind to prevent lookup overhead.
this.tick = this.tick.bind(this);
// Fast props.
this.position = [0, 0];
this.visibleAabb = [0, 0, 0, 0];
// Fast path for instance.
if ('undefined' !== typeof json) { if ('undefined' !== typeof json) {
this.fromJSON(json); this.fromJSON(json);
} }
// Bind to prevent lookup overhead.
this.tick = this.tick.bind(this);
} }
acceptPacket(packet) { acceptPacket(packet) {

View File

@ -22,7 +22,6 @@ export class EntityList extends decorate(class {}) {
this._entityTickers = [] this._entityTickers = []
this._flatEntities = []; this._flatEntities = [];
this._quadTree = new QuadTree(); this._quadTree = new QuadTree();
this.initializeSynchronizedChildren();
} }
*[Symbol.iterator]() { *[Symbol.iterator]() {
@ -76,7 +75,7 @@ export class EntityList extends decorate(class {}) {
switch (step.op) { switch (step.op) {
case 'add': case 'add':
// New entity. Create with patch as traits. // New entity. Create with patch as traits.
const newEntity = (new Entity()).fromJSON({ const newEntity = new Entity({
traits: step.value, traits: step.value,
}); });
newEntity.instanceUuid = uuid; newEntity.instanceUuid = uuid;

View File

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

View File

@ -33,7 +33,8 @@ export class Positioned extends decorate(Trait) {
const x = this.state.get('x') >> 2; const x = this.state.get('x') >> 2;
const y = this.state.get('y') >> 2; const y = this.state.get('y') >> 2;
this._position = [x, y]; this._position = [x, y];
this.entity.position = [x, y]; this.entity.position[0] = x;
this.entity.position[1] = y;
if (AVOCADO_CLIENT) { if (AVOCADO_CLIENT) {
this._relaxServerPositionConstraintIfNearerThan = 0; this._relaxServerPositionConstraintIfNearerThan = 0;
this.serverPosition = this._position; this.serverPosition = this._position;
@ -50,7 +51,8 @@ export class Positioned extends decorate(Trait) {
} }
on_positionChanged(oldPosition, newPosition) { on_positionChanged(oldPosition, newPosition) {
this.entity.position = newPosition; this.entity.position[0] = newPosition[0];
this.entity.position[1] = newPosition[1];
if (AVOCADO_SERVER) { if (AVOCADO_SERVER) {
const x = newPosition[0] << 2; const x = newPosition[0] << 2;
const y = newPosition[1] << 2; const y = newPosition[1] << 2;

View File

@ -57,7 +57,6 @@ export class Visible extends decorate(Trait) {
this._container.isVisible = this.state.get('isVisible'); this._container.isVisible = this.state.get('isVisible');
} }
this._rawVisibleAabb = [0, 0, 0, 0]; this._rawVisibleAabb = [0, 0, 0, 0];
this.entity.visibleAabb = [0, 0, 0, 0];
this.scheduledBoundingBoxUpdate = true; this.scheduledBoundingBoxUpdate = true;
this.trackPosition = this.params.trackPosition; this.trackPosition = this.params.trackPosition;
const scale = this.state.get('visibleScale'); const scale = this.state.get('visibleScale');
@ -184,10 +183,14 @@ export class Visible extends decorate(Trait) {
} }
translateVisibleAabb() { translateVisibleAabb() {
this.entity.visibleAabb = Rectangle.translated( const visibleAabb = Rectangle.translated(
this._rawVisibleAabb, this._rawVisibleAabb,
this.entity.position this.entity.position
); );
this.entity.visibleAabb[0] = visibleAabb[0];
this.entity.visibleAabb[1] = visibleAabb[1];
this.entity.visibleAabb[2] = visibleAabb[2];
this.entity.visibleAabb[3] = visibleAabb[3];
this.entity.emit('visibleAabbChanged'); this.entity.emit('visibleAabbChanged');
} }

View File

@ -14,12 +14,17 @@ export function Synchronized(Superclass) {
constructor(...args) { constructor(...args) {
super(...args); super(...args);
this.state = I.Map(); this.state = I.Map();
this._childrenNeedInitialization = true;
this._childrenWithState = [] this._childrenWithState = []
this._childrenWithoutState = []; this._childrenWithoutState = [];
this._childrenTickers = []; this._childrenTickers = [];
} }
initializeSynchronizedChildren() { ensureChildrenAreSynchronized() {
if (!this._childrenNeedInitialization) {
return;
}
this._childrenNeedInitialization = false;
const synchronizedChildren = this.synchronizedChildren(); const synchronizedChildren = this.synchronizedChildren();
for (let i = 0; i < synchronizedChildren.length; ++i) { for (let i = 0; i < synchronizedChildren.length; ++i) {
const key = synchronizedChildren[i]; const key = synchronizedChildren[i];
@ -84,6 +89,7 @@ export function Synchronized(Superclass) {
} }
tickSynchronized(elapsed) { tickSynchronized(elapsed) {
this.ensureChildrenAreSynchronized();
for (let i = 0; i < this._childrenTickers.length; ++i) { for (let i = 0; i < this._childrenTickers.length; ++i) {
this._childrenTickers[i](elapsed); this._childrenTickers[i](elapsed);
} }

View File

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

View File

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