perf: faster dirty entities
This commit is contained in:
parent
f2860eed06
commit
eb7fdf4f78
|
@ -85,8 +85,8 @@ export class Entity extends decorate(Resource) {
|
|||
constructor(json) {
|
||||
super();
|
||||
this._hooks = {};
|
||||
this.isDirty = true;
|
||||
this._traits = {};
|
||||
this._traitsTypesDirty = [];
|
||||
this._traitsFlat = [];
|
||||
this._traitTickers = [];
|
||||
this._traitRenderTickers = [];
|
||||
|
@ -156,7 +156,10 @@ export class Entity extends decorate(Resource) {
|
|||
});
|
||||
}
|
||||
// Add state.
|
||||
this.state = this._setInstanceState(this.state, type, instance);
|
||||
this.state = this.state.set(type, I.Map({
|
||||
params: instance.params,
|
||||
state: instance.state,
|
||||
}))
|
||||
// Track trait.
|
||||
this._traits[type] = instance;
|
||||
this._traitsFlat.push(instance);
|
||||
|
@ -238,12 +241,13 @@ export class Entity extends decorate(Resource) {
|
|||
}
|
||||
this.addTrait(type, step.value);
|
||||
instance = this._traits[type];
|
||||
this.state = this.state.setIn([type, 'params'], instance.params);
|
||||
}
|
||||
else {
|
||||
// Accept state.
|
||||
instance.patchState([step]);
|
||||
}
|
||||
this.state = this._setInstanceState(this.state, type, instance);
|
||||
this.state = this.state.setIn([type, 'state'], instance.state);
|
||||
}
|
||||
|
||||
renderTick(elapsed) {
|
||||
|
@ -318,12 +322,11 @@ export class Entity extends decorate(Resource) {
|
|||
types.forEach((type) => this.removeTrait(type));
|
||||
}
|
||||
|
||||
_setInstanceState(state, type, instance) {
|
||||
return state.setIn(
|
||||
[type, 'state'], instance.state
|
||||
).setIn(
|
||||
[type, 'params'], instance.params
|
||||
);
|
||||
setTraitDirty(type) {
|
||||
this._traitsTypesDirty.push(type);
|
||||
if (this.is('listed')) {
|
||||
this.list && this.list.markEntityDirty(this);
|
||||
}
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
|
@ -337,18 +340,13 @@ export class Entity extends decorate(Resource) {
|
|||
|
||||
tickMutateState() {
|
||||
this.state = this.state.withMutations((state) => {
|
||||
for (let i = 0; i < this._traitsFlat.length; i++) {
|
||||
const instance = this._traitsFlat[i];
|
||||
if (!instance.isDirty) {
|
||||
continue;
|
||||
}
|
||||
instance.isDirty = false;
|
||||
if (this.is('listed')) {
|
||||
this.list && this.list.markEntityDirty(this);
|
||||
}
|
||||
this._setInstanceState(state, instance.constructor.type(), instance);
|
||||
for (let i = 0; i < this._traitsTypesDirty.length; i++) {
|
||||
const type = this._traitsTypesDirty[i];
|
||||
const instance = this._traits[type];
|
||||
state.setIn([type, 'state'], instance.state);
|
||||
}
|
||||
});
|
||||
this._traitsTypesDirty = [];
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
|
|
@ -16,7 +16,6 @@ export class Trait extends decorate(class {}) {
|
|||
super();
|
||||
this.entity = entity;
|
||||
const ctor = this.constructor;
|
||||
this.isDirty = true;
|
||||
this._memoizedListeners = undefined;
|
||||
this.params = Object.assign({}, ctor.defaultParams(), params);
|
||||
this.state = I.fromJS(ctor.defaultState()).merge(I.fromJS(state));
|
||||
|
@ -120,41 +119,10 @@ export function StateProperty(key, meta = {}) {
|
|||
return this.${transformedProperty};
|
||||
`);
|
||||
meta.set = meta.set || new Function('value', `
|
||||
this.isDirty = true;
|
||||
this.entity.setTraitDirty(this.constructor.type());
|
||||
this.${transformedProperty} = value;
|
||||
this.state = this.state.set('${key}', value);
|
||||
`);
|
||||
return Property(key, meta)(Superclass);
|
||||
}
|
||||
}
|
||||
|
||||
StateProperty.Vector = (vector, x, y, meta = {}) => {
|
||||
return (Superclass) => {
|
||||
meta.default = undefined;
|
||||
meta.emit = meta.emit || function(...args) {
|
||||
this.entity.emit(...args);
|
||||
};
|
||||
meta.get = meta.get || function() {
|
||||
return [
|
||||
this.state.get(x),
|
||||
this.state.get(y),
|
||||
];
|
||||
};
|
||||
meta.set = meta.set || function(vector) {
|
||||
if (meta.track && meta.emit) {
|
||||
if (this.state.get(x) !== vector[0]) {
|
||||
meta.emit.call(this, `${x}Changed`, this.state.get(x), vector[0]);
|
||||
}
|
||||
if (this.state.get(y) !== vector[1]) {
|
||||
meta.emit.call(this, `${y}Changed`, this.state.get(y), vector[1]);
|
||||
}
|
||||
}
|
||||
this.isDirty = true;
|
||||
this.state = this.state.merge({
|
||||
[x]: vector[0],
|
||||
[y]: vector[1],
|
||||
});
|
||||
};
|
||||
return Vector.Mixin(vector, x, y, meta)(Superclass);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ export class Positioned extends decorate(Trait) {
|
|||
this.state = this.state.withMutations((state) => {
|
||||
state.set('x', x).set('y', y);
|
||||
});
|
||||
this.isDirty = true;
|
||||
this.entity.setTraitDirty('positioned');
|
||||
}
|
||||
this.entity.emit('positionChanged', oldPosition, newPosition);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user