refactor: names

This commit is contained in:
cha0s 2024-06-15 19:38:49 -05:00
parent 95a8e5f13e
commit 5b2db45e94
9 changed files with 127 additions and 124 deletions

View File

@ -8,14 +8,14 @@ const specificationsOrClasses = gather(
); );
const Components = {}; const Components = {};
for (const name in specificationsOrClasses) { for (const componentName in specificationsOrClasses) {
const specificationOrClass = specificationsOrClasses[name]; const specificationOrClass = specificationsOrClasses[componentName];
if (specificationOrClass instanceof Base) { if (specificationOrClass instanceof Base) {
Components[name] = specificationOrClass; Components[componentName] = specificationOrClass;
} }
else { else {
Components[name] = class Component extends Arbitrary { Components[componentName] = class Component extends Arbitrary {
static name = name; static name = componentName;
static schema = new Schema({ static schema = new Schema({
type: 'object', type: 'object',
properties: specificationOrClass, properties: specificationOrClass,

View File

@ -10,22 +10,22 @@ export default class Ecs {
$$caret = 1; $$caret = 1;
Components = {};
diff = {}; diff = {};
Systems = {}; Systems = {};
Types = {};
$$entities = {}; $$entities = {};
$$entityFactory = new EntityFactory(); $$entityFactory = new EntityFactory();
constructor({Systems, Types} = {}) { constructor({Systems, Components} = {}) {
for (const name in Types) { for (const componentName in Components) {
this.Types[name] = new Types[name](this); this.Components[componentName] = new Components[componentName](this);
} }
for (const name in Systems) { for (const systemName in Systems) {
this.Systems[name] = new Systems[name](this); this.Systems[systemName] = new Systems[systemName](this);
} }
} }
@ -42,12 +42,12 @@ export default class Ecs {
} }
const componentsToRemove = []; const componentsToRemove = [];
const componentsToUpdate = {}; const componentsToUpdate = {};
for (const i in components) { for (const componentName in components) {
if (false === components[i]) { if (false === components[componentName]) {
componentsToRemove.push(i); componentsToRemove.push(componentName);
} }
else { else {
componentsToUpdate[i] = components[i]; componentsToUpdate[componentName] = components[componentName];
} }
} }
if (componentsToRemove.length > 0) { if (componentsToRemove.length > 0) {
@ -84,24 +84,24 @@ export default class Ecs {
const creating = {}; const creating = {};
for (let i = 0; i < specificsList.length; i++) { for (let i = 0; i < specificsList.length; i++) {
const [entityId, components] = specificsList[i]; const [entityId, components] = specificsList[i];
const componentKeys = []; const componentNames = [];
for (const name in components) { for (const componentName in components) {
if (this.Types[name]) { if (this.Components[componentName]) {
componentKeys.push(name); componentNames.push(componentName);
} }
} }
entityIds.push(entityId); entityIds.push(entityId);
this.rebuild(entityId, () => componentKeys); this.rebuild(entityId, () => componentNames);
for (const component of componentKeys) { for (const componentName of componentNames) {
if (!creating[component]) { if (!creating[componentName]) {
creating[component] = []; creating[componentName] = [];
} }
creating[component].push([entityId, components[component]]); creating[componentName].push([entityId, components[componentName]]);
} }
this.markChange(entityId, components); this.markChange(entityId, components);
} }
for (const i in creating) { for (const i in creating) {
this.Types[i].createMany(creating[i]); this.Components[i].createMany(creating[i]);
} }
this.reindex(entityIds); this.reindex(entityIds);
return entityIds; return entityIds;
@ -112,13 +112,13 @@ export default class Ecs {
} }
deindex(entityIds) { deindex(entityIds) {
for (const name in this.Systems) { for (const systemName in this.Systems) {
this.Systems[name].deindex(entityIds); this.Systems[systemName].deindex(entityIds);
} }
} }
static deserialize(ecs, view) { static deserialize(ecs, view) {
const types = Object.keys(ecs.Types); const componentNames = Object.keys(ecs.Components);
const {entities, systems} = decoder.decode(view.buffer); const {entities, systems} = decoder.decode(view.buffer);
for (const system of systems) { for (const system of systems) {
ecs.system(system).active = true; ecs.system(system).active = true;
@ -129,7 +129,10 @@ export default class Ecs {
max = Math.max(max, parseInt(id)); max = Math.max(max, parseInt(id));
specifics.push([ specifics.push([
parseInt(id), parseInt(id),
Object.fromEntries(Object.entries(entities[id]).filter(([type]) => types.includes(type))), Object.fromEntries(
Object.entries(entities[id])
.filter(([componentName]) => componentNames.includes(componentName)),
),
]); ]);
} }
ecs.$$caret = max + 1; ecs.$$caret = max + 1;
@ -152,17 +155,17 @@ export default class Ecs {
if (!this.$$entities[entityId]) { if (!this.$$entities[entityId]) {
throw new Error(`can't destroy non-existent entity ${entityId}`); throw new Error(`can't destroy non-existent entity ${entityId}`);
} }
for (const component of this.$$entities[entityId].constructor.types) { for (const componentName of this.$$entities[entityId].constructor.componentNames) {
if (!destroying[component]) { if (!destroying[componentName]) {
destroying[component] = []; destroying[componentName] = [];
} }
destroying[component].push(entityId); destroying[componentName].push(entityId);
} }
this.$$entities[entityId] = undefined; this.$$entities[entityId] = undefined;
this.diff[entityId] = false; this.diff[entityId] = false;
} }
for (const i in destroying) { for (const i in destroying) {
this.Types[i].destroyMany(destroying[i]); this.Components[i].destroyMany(destroying[i]);
} }
} }
@ -197,20 +200,20 @@ export default class Ecs {
const inserting = {}; const inserting = {};
const unique = new Set(); const unique = new Set();
for (const [entityId, components] of entities) { for (const [entityId, components] of entities) {
this.rebuild(entityId, (types) => [...new Set(types.concat(Object.keys(components)))]); this.rebuild(entityId, (componentNames) => [...new Set(componentNames.concat(Object.keys(components)))]);
const diff = {}; const diff = {};
for (const component in components) { for (const componentName in components) {
if (!inserting[component]) { if (!inserting[componentName]) {
inserting[component] = []; inserting[componentName] = [];
} }
diff[component] = {}; diff[componentName] = {};
inserting[component].push([entityId, components[component]]); inserting[componentName].push([entityId, components[componentName]]);
} }
unique.add(entityId); unique.add(entityId);
this.markChange(entityId, diff); this.markChange(entityId, diff);
} }
for (const component in inserting) { for (const componentName in inserting) {
this.Types[component].insertMany(inserting[component]); this.Components[componentName].insertMany(inserting[componentName]);
} }
this.reindex(unique.values()); this.reindex(unique.values());
} }
@ -223,38 +226,38 @@ export default class Ecs {
// Created? // Created?
else if (!this.diff[entityId]) { else if (!this.diff[entityId]) {
const filtered = {}; const filtered = {};
for (const name in components) { for (const componentName in components) {
filtered[name] = false === components[name] filtered[componentName] = false === components[componentName]
? false ? false
: this.Types[name].constructor.filterDefaults(components[name]); : this.Components[componentName].constructor.filterDefaults(components[componentName]);
} }
this.diff[entityId] = filtered; this.diff[entityId] = filtered;
} }
// Otherwise, merge. // Otherwise, merge.
else { else {
for (const name in components) { for (const componentName in components) {
this.diff[entityId][name] = false === components[name] this.diff[entityId][componentName] = false === components[componentName]
? false ? false
: this.Types[name].mergeDiff( : this.Components[componentName].mergeDiff(
this.diff[entityId][name] || {}, this.diff[entityId][componentName] || {},
components[name], components[componentName],
); );
} }
} }
} }
rebuild(entityId, types) { rebuild(entityId, componentNames) {
let existing = []; let existing = [];
if (this.$$entities[entityId]) { if (this.$$entities[entityId]) {
existing.push(...this.$$entities[entityId].constructor.types); existing.push(...this.$$entities[entityId].constructor.componentNames);
} }
const Class = this.$$entityFactory.makeClass(types(existing), this.Types); const Class = this.$$entityFactory.makeClass(componentNames(existing), this.Components);
this.$$entities[entityId] = new Class(entityId); this.$$entities[entityId] = new Class(entityId);
} }
reindex(entityIds) { reindex(entityIds) {
for (const name in this.Systems) { for (const systemName in this.Systems) {
this.Systems[name].reindex(entityIds); this.Systems[systemName].reindex(entityIds);
} }
} }
@ -268,18 +271,18 @@ export default class Ecs {
for (const [entityId, components] of entities) { for (const [entityId, components] of entities) {
unique.add(entityId); unique.add(entityId);
const diff = {}; const diff = {};
for (const component of components) { for (const componentName of components) {
diff[component] = false; diff[componentName] = false;
if (!removing[component]) { if (!removing[componentName]) {
removing[component] = []; removing[componentName] = [];
} }
removing[component].push(entityId); removing[componentName].push(entityId);
} }
this.markChange(entityId, diff); this.markChange(entityId, diff);
this.rebuild(entityId, (types) => types.filter((type) => !components.includes(type))); this.rebuild(entityId, (componentNames) => componentNames.filter((type) => !components.includes(type)));
} }
for (const component in removing) { for (const componentName in removing) {
this.Types[component].destroyMany(removing[component]); this.Components[componentName].destroyMany(removing[componentName]);
} }
this.reindex(unique.values()); this.reindex(unique.values());
} }
@ -301,7 +304,7 @@ export default class Ecs {
let size = 0; let size = 0;
// # of components. // # of components.
size += 2; size += 2;
for (const type in this.Types) { for (const type in this.Components) {
size += Schema.sizeOf(type, {type: 'string'}); size += Schema.sizeOf(type, {type: 'string'});
} }
// # of entities. // # of entities.
@ -312,19 +315,19 @@ export default class Ecs {
return size; return size;
} }
system(name) { system(systemName) {
return this.Systems[name]; return this.Systems[systemName];
} }
tick(elapsed) { tick(elapsed) {
for (const name in this.Systems) { for (const systemName in this.Systems) {
if (this.Systems[name].active) { if (this.Systems[systemName].active) {
this.Systems[name].tick(elapsed); this.Systems[systemName].tick(elapsed);
} }
} }
for (const name in this.Systems) { for (const systemName in this.Systems) {
if (this.Systems[name].active) { if (this.Systems[systemName].active) {
this.Systems[name].finalize(elapsed); this.Systems[systemName].finalize(elapsed);
} }
} }
this.tickDestruction(); this.tickDestruction();
@ -332,8 +335,8 @@ export default class Ecs {
tickDestruction() { tickDestruction() {
const unique = new Set(); const unique = new Set();
for (const name in this.Systems) { for (const systemName in this.Systems) {
const System = this.Systems[name]; const System = this.Systems[systemName];
if (System.active) { if (System.active) {
for (let j = 0; j < System.destroying.length; j++) { for (let j = 0; j < System.destroying.length; j++) {
unique.add(System.destroying[j]); unique.add(System.destroying[j]);
@ -352,9 +355,9 @@ export default class Ecs {
entities[id] = this.$$entities[id].toJSON(); entities[id] = this.$$entities[id].toJSON();
} }
const systems = []; const systems = [];
for (const name in this.Systems) { for (const systemName in this.Systems) {
if (this.Systems[name].active) { if (this.Systems[systemName].active) {
systems.push(name); systems.push(systemName);
} }
} }
return { return {

View File

@ -68,14 +68,14 @@ test('activates and deactivates systems at runtime', () => {
}); });
test('creates entities with components', () => { test('creates entities with components', () => {
const ecs = new Ecs({Types: {Empty, Position}}); const ecs = new Ecs({Components: {Empty, Position}});
const entity = ecs.create({Empty: {}, Position: {y: 128}}); const entity = ecs.create({Empty: {}, Position: {y: 128}});
expect(JSON.stringify(ecs.get(entity))) expect(JSON.stringify(ecs.get(entity)))
.to.deep.equal(JSON.stringify({Empty: {}, Position: {y: 128}})); .to.deep.equal(JSON.stringify({Empty: {}, Position: {y: 128}}));
}); });
test("removes entities' components", () => { test("removes entities' components", () => {
const ecs = new Ecs({Types: {Empty, Position}}); const ecs = new Ecs({Components: {Empty, Position}});
const entity = ecs.create({Empty: {}, Position: {y: 128}}); const entity = ecs.create({Empty: {}, Position: {y: 128}});
ecs.remove(entity, ['Position']); ecs.remove(entity, ['Position']);
expect(JSON.stringify(ecs.get(entity))) expect(JSON.stringify(ecs.get(entity)))
@ -83,14 +83,14 @@ test("removes entities' components", () => {
}); });
test('gets entities', () => { test('gets entities', () => {
const ecs = new Ecs({Types: {Empty, Position}}); const ecs = new Ecs({Components: {Empty, Position}});
const entity = ecs.create({Empty: {}, Position: {y: 128}}); const entity = ecs.create({Empty: {}, Position: {y: 128}});
expect(JSON.stringify(ecs.get(entity))) expect(JSON.stringify(ecs.get(entity)))
.to.deep.equal(JSON.stringify({Empty: {}, Position: {y: 128}})); .to.deep.equal(JSON.stringify({Empty: {}, Position: {y: 128}}));
}); });
test('destroys entities', () => { test('destroys entities', () => {
const ecs = new Ecs({Types: {Empty, Position}}); const ecs = new Ecs({Components: {Empty, Position}});
const entity = ecs.create({Empty: {}, Position: {y: 128}}); const entity = ecs.create({Empty: {}, Position: {y: 128}});
expect(JSON.stringify(ecs.get(entity))) expect(JSON.stringify(ecs.get(entity)))
.to.deep.equal(JSON.stringify({Empty: {}, Position: {y: 128}})); .to.deep.equal(JSON.stringify({Empty: {}, Position: {y: 128}}));
@ -106,7 +106,7 @@ test('destroys entities', () => {
}); });
test('inserts components into entities', () => { test('inserts components into entities', () => {
const ecs = new Ecs({Types: {Empty, Position}}); const ecs = new Ecs({Components: {Empty, Position}});
const entity = ecs.create({Empty: {}}); const entity = ecs.create({Empty: {}});
ecs.insert(entity, {Position: {y: 128}}); ecs.insert(entity, {Position: {y: 128}});
expect(JSON.stringify(ecs.get(entity))) expect(JSON.stringify(ecs.get(entity)))
@ -123,6 +123,7 @@ test('ticks systems', () => {
z: {type: 'int32'}, z: {type: 'int32'},
}); });
const ecs = new Ecs({ const ecs = new Ecs({
Components: {Momentum, Position},
Systems: { Systems: {
Physics: class Physics extends System { Physics: class Physics extends System {
@ -142,7 +143,6 @@ test('ticks systems', () => {
}, },
}, },
Types: {Momentum, Position},
}); });
ecs.system('Physics').active = true; ecs.system('Physics').active = true;
const entity = ecs.create({Momentum: {}, Position: {y: 128}}); const entity = ecs.create({Momentum: {}, Position: {y: 128}});
@ -220,6 +220,7 @@ test('schedules entities to be deleted when ticking systems', () => {
test('adds components to and remove components from entities when ticking systems', () => { test('adds components to and remove components from entities when ticking systems', () => {
let addLength, removeLength; let addLength, removeLength;
const ecs = new Ecs({ const ecs = new Ecs({
Components: {Foo: wrapSpecification('Foo', {bar: {type: 'uint8'}})},
Systems: { Systems: {
AddComponent: class extends System { AddComponent: class extends System {
static queries() { static queries() {
@ -248,7 +249,6 @@ test('adds components to and remove components from entities when ticking system
} }
}, },
}, },
Types: {Foo: wrapSpecification('Foo', {bar: {type: 'uint8'}})},
}); });
ecs.system('AddComponent').active = true; ecs.system('AddComponent').active = true;
ecs.create(); ecs.create();
@ -275,7 +275,7 @@ test('generates coalesced diffs for entity creation', () => {
}); });
test('generates diffs for adding and removing components', () => { test('generates diffs for adding and removing components', () => {
const ecs = new Ecs({Types: {Position}}); const ecs = new Ecs({Components: {Position}});
let entity; let entity;
entity = ecs.create(); entity = ecs.create();
ecs.setClean(); ecs.setClean();
@ -291,7 +291,7 @@ test('generates diffs for adding and removing components', () => {
}); });
test('generates diffs for empty components', () => { test('generates diffs for empty components', () => {
const ecs = new Ecs({Types: {Empty}}); const ecs = new Ecs({Components: {Empty}});
let entity; let entity;
entity = ecs.create({Empty}); entity = ecs.create({Empty});
expect(ecs.diff) expect(ecs.diff)
@ -303,7 +303,7 @@ test('generates diffs for empty components', () => {
}); });
test('generates diffs for entity mutations', () => { test('generates diffs for entity mutations', () => {
const ecs = new Ecs({Types: {Position}}); const ecs = new Ecs({Components: {Position}});
let entity; let entity;
entity = ecs.create({Position: {}}); entity = ecs.create({Position: {}});
ecs.setClean(); ecs.setClean();
@ -316,7 +316,7 @@ test('generates diffs for entity mutations', () => {
}); });
test('generates coalesced diffs for components', () => { test('generates coalesced diffs for components', () => {
const ecs = new Ecs({Types: {Position}}); const ecs = new Ecs({Components: {Position}});
let entity; let entity;
entity = ecs.create({Position}); entity = ecs.create({Position});
ecs.remove(entity, ['Position']); ecs.remove(entity, ['Position']);
@ -328,7 +328,7 @@ test('generates coalesced diffs for components', () => {
}); });
test('generates coalesced diffs for mutations', () => { test('generates coalesced diffs for mutations', () => {
const ecs = new Ecs({Types: {Position}}); const ecs = new Ecs({Components: {Position}});
let entity; let entity;
entity = ecs.create({Position}); entity = ecs.create({Position});
ecs.setClean(); ecs.setClean();
@ -350,7 +350,7 @@ test('generates diffs for deletions', () => {
}); });
test('applies creation patches', () => { test('applies creation patches', () => {
const ecs = new Ecs({Types: {Position}}); const ecs = new Ecs({Components: {Position}});
ecs.apply({16: {Position: {x: 64}}}); ecs.apply({16: {Position: {x: 64}}});
expect(Array.from(ecs.entities).length) expect(Array.from(ecs.entities).length)
.to.equal(1); .to.equal(1);
@ -359,7 +359,7 @@ test('applies creation patches', () => {
}); });
test('applies update patches', () => { test('applies update patches', () => {
const ecs = new Ecs({Types: {Position}}); const ecs = new Ecs({Components: {Position}});
ecs.createSpecific(16, {Position: {x: 64}}); ecs.createSpecific(16, {Position: {x: 64}});
ecs.apply({16: {Position: {x: 128}}}); ecs.apply({16: {Position: {x: 128}}});
expect(Array.from(ecs.entities).length) expect(Array.from(ecs.entities).length)
@ -369,7 +369,7 @@ test('applies update patches', () => {
}); });
test('applies entity deletion patches', () => { test('applies entity deletion patches', () => {
const ecs = new Ecs({Types: {Position}}); const ecs = new Ecs({Components: {Position}});
ecs.createSpecific(16, {Position: {x: 64}}); ecs.createSpecific(16, {Position: {x: 64}});
ecs.apply({16: false}); ecs.apply({16: false});
expect(Array.from(ecs.entities).length) expect(Array.from(ecs.entities).length)
@ -377,17 +377,17 @@ test('applies entity deletion patches', () => {
}); });
test('applies component deletion patches', () => { test('applies component deletion patches', () => {
const ecs = new Ecs({Types: {Empty, Position}}); const ecs = new Ecs({Components: {Empty, Position}});
ecs.createSpecific(16, {Empty: {}, Position: {x: 64}}); ecs.createSpecific(16, {Empty: {}, Position: {x: 64}});
expect(ecs.get(16).constructor.types) expect(ecs.get(16).constructor.componentNames)
.to.deep.equal(['Empty', 'Position']); .to.deep.equal(['Empty', 'Position']);
ecs.apply({16: {Empty: false}}); ecs.apply({16: {Empty: false}});
expect(ecs.get(16).constructor.types) expect(ecs.get(16).constructor.componentNames)
.to.deep.equal(['Position']); .to.deep.equal(['Position']);
}); });
test('calculates entity size', () => { test('calculates entity size', () => {
const ecs = new Ecs({Types: {Empty, Position}}); const ecs = new Ecs({Components: {Empty, Position}});
ecs.createSpecific(1, {Empty: {}, Position: {}}); ecs.createSpecific(1, {Empty: {}, Position: {}});
// ID + # of components + Empty + Position + x + y + z // ID + # of components + Empty + Position + x + y + z
// 4 + 2 + 2 + 4 + 2 + 4 + 4 + 4 + 4 = 30 // 4 + 2 + 2 + 4 + 2 + 4 + 4 + 4 + 4 = 30
@ -396,7 +396,7 @@ test('calculates entity size', () => {
}); });
test('serializes and deserializes', () => { test('serializes and deserializes', () => {
const ecs = new Ecs({Types: {Empty, Name, Position}}); const ecs = new Ecs({Components: {Empty, Name, Position}});
ecs.createSpecific(1, {Empty: {}, Position: {x: 64}}); ecs.createSpecific(1, {Empty: {}, Position: {x: 64}});
ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}}); ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}});
expect(ecs.toJSON()) expect(ecs.toJSON())
@ -409,14 +409,14 @@ test('serializes and deserializes', () => {
}); });
const view = Ecs.serialize(ecs); const view = Ecs.serialize(ecs);
const deserialized = Ecs.deserialize( const deserialized = Ecs.deserialize(
new Ecs({Types: {Empty, Name, Position}}), new Ecs({Components: {Empty, Name, Position}}),
view, view,
); );
expect(Array.from(deserialized.entities).length) expect(Array.from(deserialized.entities).length)
.to.equal(2); .to.equal(2);
expect(deserialized.get(1).constructor.types) expect(deserialized.get(1).constructor.componentNames)
.to.deep.equal(['Empty', 'Position']); .to.deep.equal(['Empty', 'Position']);
expect(deserialized.get(16).constructor.types) expect(deserialized.get(16).constructor.componentNames)
.to.deep.equal(['Name', 'Position']); .to.deep.equal(['Name', 'Position']);
expect(JSON.stringify(deserialized.get(1))) expect(JSON.stringify(deserialized.get(1)))
.to.equal(JSON.stringify({Empty: {}, Position: {x: 64}})) .to.equal(JSON.stringify({Empty: {}, Position: {x: 64}}))
@ -429,12 +429,12 @@ test('serializes and deserializes', () => {
}); });
test('deserializes from compatible ECS', () => { test('deserializes from compatible ECS', () => {
const ecs = new Ecs({Types: {Empty, Name, Position}}); const ecs = new Ecs({Components: {Empty, Name, Position}});
ecs.createSpecific(1, {Empty: {}, Position: {x: 64}}); ecs.createSpecific(1, {Empty: {}, Position: {x: 64}});
ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}}); ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}});
const view = Ecs.serialize(ecs); const view = Ecs.serialize(ecs);
const deserialized = Ecs.deserialize( const deserialized = Ecs.deserialize(
new Ecs({Types: {Empty, Name}}), new Ecs({Components: {Empty, Name}}),
view, view,
); );
expect(deserialized.get(1).toJSON()) expect(deserialized.get(1).toJSON())

View File

@ -7,8 +7,8 @@ export default class EntityFactory {
$$tries = new Node(); $$tries = new Node();
makeClass(types, Types) { makeClass(componentNames, Components) {
const sorted = types.toSorted(); const sorted = componentNames.toSorted();
let walk = this.$$tries; let walk = this.$$tries;
let i = 0; let i = 0;
while (i < sorted.length) { while (i < sorted.length) {
@ -20,14 +20,14 @@ export default class EntityFactory {
} }
if (!walk.class) { if (!walk.class) {
class Entity { class Entity {
static types = sorted; static componentNames = sorted;
constructor(id) { constructor(id) {
this.id = id; this.id = id;
} }
size() { size() {
let size = 0; let size = 0;
for (const component of this.constructor.types) { for (const componentName of this.constructor.componentNames) {
const instance = Types[component]; const instance = Components[componentName];
size += 2 + 4 + instance.constructor.schema.sizeOf(instance.get(this.id)); size += 2 + 4 + instance.constructor.schema.sizeOf(instance.get(this.id));
} }
// ID + # of components. // ID + # of components.
@ -37,7 +37,7 @@ export default class EntityFactory {
const properties = {}; const properties = {};
for (const type of sorted) { for (const type of sorted) {
properties[type] = {}; properties[type] = {};
const get = Types[type].get.bind(Types[type]); const get = Components[type].get.bind(Components[type]);
properties[type].get = function() { properties[type].get = function() {
return get(this.id); return get(this.id);
}; };

View File

@ -4,15 +4,15 @@ export default class Query {
$$index = new Set(); $$index = new Set();
constructor(parameters, Types) { constructor(parameters, Components) {
for (let i = 0; i < parameters.length; ++i) { for (let i = 0; i < parameters.length; ++i) {
const parameter = parameters[i]; const parameter = parameters[i];
switch (parameter.charCodeAt(0)) { switch (parameter.charCodeAt(0)) {
case '!'.charCodeAt(0): case '!'.charCodeAt(0):
this.$$criteria.without.push(Types[parameter.slice(1)]); this.$$criteria.without.push(Components[parameter.slice(1)]);
break; break;
default: default:
this.$$criteria.with.push(Types[parameter]); this.$$criteria.with.push(Components[parameter]);
break; break;
} }
} }

View File

@ -18,13 +18,13 @@ const A = new (wrapSpecification('A', {a: {type: 'int32', defaultValue: 420}}));
const B = new (wrapSpecification('B', {b: {type: 'int32', defaultValue: 69}})); const B = new (wrapSpecification('B', {b: {type: 'int32', defaultValue: 69}}));
const C = new (wrapSpecification('C', {c: {type: 'int32'}})); const C = new (wrapSpecification('C', {c: {type: 'int32'}}));
const Types = {A, B, C}; const Components = {A, B, C};
Types.A.createMany([[2], [3]]); Components.A.createMany([[2], [3]]);
Types.B.createMany([[1], [2]]); Components.B.createMany([[1], [2]]);
Types.C.createMany([[2], [4]]); Components.C.createMany([[2], [4]]);
function testQuery(parameters, expected) { function testQuery(parameters, expected) {
const query = new Query(parameters, Types); const query = new Query(parameters, Components);
query.reindex([1, 2, 3]); query.reindex([1, 2, 3]);
expect(query.count) expect(query.count)
.to.equal(expected.length); .to.equal(expected.length);
@ -51,7 +51,7 @@ test('can query excluding', () => {
}); });
test('can deindex', () => { test('can deindex', () => {
const query = new Query(['A'], Types); const query = new Query(['A'], Components);
query.reindex([1, 2, 3]); query.reindex([1, 2, 3]);
expect(query.count) expect(query.count)
.to.equal(2); .to.equal(2);
@ -74,7 +74,7 @@ test('can reindex', () => {
}); });
test('can select', () => { test('can select', () => {
const query = new Query(['A'], Types); const query = new Query(['A'], Components);
query.reindex([1, 2, 3]); query.reindex([1, 2, 3]);
const it = query.select(); const it = query.select();
const result = it.next(); const result = it.next();

View File

@ -15,7 +15,7 @@ export default class System {
this.ecs = ecs; this.ecs = ecs;
const queries = this.constructor.queries(); const queries = this.constructor.queries();
for (const i in queries) { for (const i in queries) {
this.queries[i] = new Query(queries[i], ecs.Types); this.queries[i] = new Query(queries[i], ecs.Components);
} }
this.reindex(ecs.entities); this.reindex(ecs.entities);
} }

View File

@ -5,8 +5,8 @@ import {
TPS, TPS,
} from '@/constants.js'; } from '@/constants.js';
import Ecs from '@/ecs/ecs.js'; import Ecs from '@/ecs/ecs.js';
import Components from '@/ecs-components/index.js';
import Systems from '@/ecs-systems/index.js'; import Systems from '@/ecs-systems/index.js';
import Types from '@/ecs-components/index.js';
import {decode, encode} from '@/packets/index.js'; import {decode, encode} from '@/packets/index.js';
export default class Engine { export default class Engine {
@ -60,7 +60,7 @@ export default class Engine {
} }
createEcs() { createEcs() {
return new Ecs({Systems, Types}); return new Ecs({Components, Systems});
} }
async createHomestead(id) { async createHomestead(id) {

View File

@ -3,15 +3,15 @@ import {useState} from 'react';
import {RESOLUTION} from '@/constants.js'; import {RESOLUTION} from '@/constants.js';
import Ecs from '@/ecs/ecs.js'; import Ecs from '@/ecs/ecs.js';
import Components from '@/ecs-components/index.js';
import Systems from '@/ecs-systems/index.js'; import Systems from '@/ecs-systems/index.js';
import Types from '@/ecs-components/index.js';
import usePacket from '@/hooks/use-packet.js'; import usePacket from '@/hooks/use-packet.js';
import Entities from './entities.jsx'; import Entities from './entities.jsx';
import TileLayer from './tile-layer.jsx'; import TileLayer from './tile-layer.jsx';
export default function EcsComponent() { export default function EcsComponent() {
const [ecs] = useState(new Ecs({Systems, Types})); const [ecs] = useState(new Ecs({Components, Systems}));
const [entities, setEntities] = useState({}); const [entities, setEntities] = useState({});
const [mainEntity, setMainEntity] = useState(); const [mainEntity, setMainEntity] = useState();
usePacket('Tick', (payload) => { usePacket('Tick', (payload) => {