refactor: API

This commit is contained in:
cha0s 2021-01-04 07:00:08 -06:00
parent 79b5353cab
commit ddce53ed21
2 changed files with 45 additions and 71 deletions

View File

@ -31,18 +31,22 @@ let numericUid = 'client' !== SIDE ? 1 : 1000000000;
export default (latus) => class Entity extends decorate(JsonResource) {
#hooks = {};
#tickingPromisesTickers = [];
#traitsFlat = [];
#traitTickers = [];
#traitRenderTickers = [];
#traitsAcceptingPackets = [];
constructor({instanceUuid, traits = []} = {}) {
super();
this._fastDirtyCheck = true;
this._hooks = {};
this._hydrationPromise = undefined;
// this._json = Entity.jsonWithDefaults(json);
this._tickingPromisesTickers = [];
this._traits = {};
this._traitsFlat = [];
this._traitTickers = [];
this._traitRenderTickers = [];
this._traitsAcceptingPackets = [];
this.once('destroyed', () => {
this.removeAllTraits();
});
@ -72,11 +76,11 @@ export default (latus) => class Entity extends decorate(JsonResource) {
addTickingPromise(tickingPromise) {
const ticker = tickingPromise.tick.bind(tickingPromise);
this._tickingPromisesTickers.push(ticker);
this.#tickingPromisesTickers.push(ticker);
return tickingPromise.then(() => {
const index = this._tickingPromisesTickers.indexOf(ticker);
const index = this.#tickingPromisesTickers.indexOf(ticker);
if (-1 !== index) {
this._tickingPromisesTickers.splice(index, 1);
this.#tickingPromisesTickers.splice(index, 1);
}
});
}
@ -92,7 +96,7 @@ export default (latus) => class Entity extends decorate(JsonResource) {
}
// Ensure dependencies.
const dependencies = Trait.dependencies();
const allTypes = this.allTraitTypes();
const allTypes = this.traitTypes();
const lacking = without(dependencies, ...allTypes);
if (lacking.length > 0) {
debug(
@ -124,23 +128,23 @@ export default (latus) => class Entity extends decorate(JsonResource) {
const hooks = Object.entries(trait.hooks());
for (let i = 0; i < hooks.length; i++) {
const [key, fn] = hooks[i];
this._hooks[key] = this._hooks[key] || [];
this._hooks[key].push({
this.#hooks[key] = this.#hooks[key] || [];
this.#hooks[key].push({
fn,
type: Trait.type,
});
}
// Track trait.
this._traits[Trait.type] = trait;
this._traitsFlat.push(trait);
this.#traitsFlat.push(trait);
if ('tick' in trait) {
this._traitTickers.push(trait.tick);
this.#traitTickers.push(trait.tick);
}
if ('renderTick' in trait) {
this._traitRenderTickers.push(trait.renderTick);
this.#traitRenderTickers.push(trait.renderTick);
}
if ('acceptPacket' in trait) {
this._traitsAcceptingPackets.push(trait);
this.#traitsAcceptingPackets.push(trait);
}
this.emit('traitAdded', Trait.type, trait);
}
@ -151,16 +155,12 @@ export default (latus) => class Entity extends decorate(JsonResource) {
}
}
allTraitTypes() {
return Object.keys(this._traits);
}
cleanPackets() {
if (!this._fastDirtyCheck) {
return;
}
for (let i = 0; i < this._traitsFlat.length; i++) {
this._traitsFlat[i].cleanPackets();
for (let i = 0; i < this.#traitsFlat.length; i++) {
this.#traitsFlat[i].cleanPackets();
}
this._fastDirtyCheck = false;
}
@ -184,10 +184,10 @@ export default (latus) => class Entity extends decorate(JsonResource) {
invokeHook(hook, ...args) {
const results = {};
if (!(hook in this._hooks)) {
if (!(hook in this.#hooks)) {
return results;
}
const values = Object.values(this._hooks[hook]);
const values = Object.values(this.#hooks[hook]);
for (let i = 0; i < values.length; i++) {
const {fn, type} = values[i];
results[type] = fastApply(null, fn, args);
@ -203,22 +203,6 @@ export default (latus) => class Entity extends decorate(JsonResource) {
return type in this._traits;
}
// static jsonWithDefaults(json) {
// if ('undefined' === typeof json) {
// return undefined;
// }
// const pristine = JSON.parse(JSON.stringify(json));
// const traits = Object.entries(json.traits);
// for (let i = 0; i < traits.length; i++) {
// const [type, trait] = traits[i];
// const {[type]: Trait} = traitFromType(latus);
// if (Trait) {
// pristine.traits[type] = merge(Trait.defaultJSON(), trait);
// }
// }
// return pristine;
// }
mergeDiff(json) {
if (!this.uri) {
return json;
@ -247,13 +231,13 @@ export default (latus) => class Entity extends decorate(JsonResource) {
}
renderTick(elapsed) {
for (let i = 0; i < this._traitRenderTickers.length; i++) {
this._traitRenderTickers[i](elapsed);
for (let i = 0; i < this.#traitRenderTickers.length; i++) {
this.#traitRenderTickers[i](elapsed);
}
}
removeAllTraits() {
const types = this.allTraitTypes();
const types = this.traitTypes();
this.removeTraits(types);
}
@ -274,8 +258,8 @@ export default (latus) => class Entity extends decorate(JsonResource) {
const hooks = Object.keys(instance.hooks());
for (let i = 0; i < hooks.length; i++) {
const hook = hooks[i];
const implementation = this._hooks[hook].find(({type: hookType}) => hookType === type);
this._hooks[hook].splice(this._hooks[hook].indexOf(implementation), 1);
const implementation = this.#hooks[hook].find(({type: hookType}) => hookType === type);
this.#hooks[hook].splice(this.#hooks[hook].indexOf(implementation), 1);
}
const {fromType: {[type]: Trait}} = traits(latus);
const properties = enumerateTraitAccessorKeys(Trait.prototype);
@ -292,16 +276,16 @@ export default (latus) => class Entity extends decorate(JsonResource) {
instance._memoizedListeners = {};
// Remove instance.
delete this._traits[type];
this._traitsFlat.splice(this._traitsFlat.indexOf(instance), 1);
this.#traitsFlat.splice(this.#traitsFlat.indexOf(instance), 1);
if ('tick' in instance) {
this._traitTickers.splice(this._traitTickers.indexOf(instance.tick), 1);
this.#traitTickers.splice(this.#traitTickers.indexOf(instance.tick), 1);
}
if ('renderTick' in instance) {
this._traitRenderTickers.splice(this._traitRenderTickers.indexOf(instance.renderTick), 1);
this.#traitRenderTickers.splice(this.#traitRenderTickers.indexOf(instance.renderTick), 1);
}
const acceptPacketIndex = this._traitsAcceptingPackets.indexOf(instance);
const acceptPacketIndex = this.#traitsAcceptingPackets.indexOf(instance);
if (-1 !== acceptPacketIndex) {
this._traitsAcceptingPackets.splice(acceptPacketIndex, 1);
this.#traitsAcceptingPackets.splice(acceptPacketIndex, 1);
}
// Unloop.
instance.entity = undefined;
@ -316,11 +300,11 @@ export default (latus) => class Entity extends decorate(JsonResource) {
}
tick(elapsed) {
for (let i = 0; i < this._traitTickers.length; i++) {
this._traitTickers[i](elapsed);
for (let i = 0; i < this.#traitTickers.length; i++) {
this.#traitTickers[i](elapsed);
}
for (let i = 0; i < this._tickingPromisesTickers.length; i++) {
this._tickingPromisesTickers[i](elapsed);
for (let i = 0; i < this.#tickingPromisesTickers.length; i++) {
this.#tickingPromisesTickers[i](elapsed);
}
}
@ -340,20 +324,6 @@ export default (latus) => class Entity extends decorate(JsonResource) {
};
}
// toJSON() {
// const json = {};
// const traits = Object.entries(this._traits);
// for (let i = 0; i < traits.length; i++) {
// const [type, trait] = traits[i];
// json[type] = trait.toJSON();
// }
// return {
// ...super.toJSON(),
// instanceUuid: this.instanceUuid,
// traits: json,
// };
// }
trait(type) {
return this._traits[type];
}
@ -362,4 +332,8 @@ export default (latus) => class Entity extends decorate(JsonResource) {
return this._traits;
}
traitTypes() {
return Object.keys(this._traits);
}
};

View File

@ -20,7 +20,7 @@ describe(name, () => {
it('has sane defaults', () => {
const entity = new Entity();
expect(entity.traits).to.deep.equal({});
expect(entity.allTraitTypes()).to.deep.equal([]);
expect(entity.traitTypes()).to.deep.equal([]);
});
it('can add and remove traits', async () => {
const entity = new Entity();