ecs: use name2cfpairs, fixed identity thing, test errors

This commit is contained in:
Steven Hugg 2022-02-22 10:59:40 -06:00
parent 37edd8268a
commit 3d05c0ed1a
4 changed files with 57 additions and 16 deletions

View File

@ -1594,19 +1594,20 @@ export class EntityManager {
} }
defineComponent(ctype: ComponentType) { defineComponent(ctype: ComponentType) {
let existing = this.components[ctype.name]; let existing = this.components[ctype.name];
// we can defer component definitions, just declare a component with 0 fields?
if (existing && existing.fields.length > 0) if (existing && existing.fields.length > 0)
throw new ECSError(`component ${ctype.name} already defined`, existing); throw new ECSError(`component ${ctype.name} already defined`, existing);
if (existing) {
existing.fields = ctype.fields;
ctype = existing;
}
for (let field of ctype.fields) { for (let field of ctype.fields) {
let list = this.name2cfpairs[field.name]; let list = this.name2cfpairs[field.name];
if (!list) list = this.name2cfpairs[field.name] = []; if (!list) list = this.name2cfpairs[field.name] = [];
list.push({ c: ctype, f: field }); list.push({ c: ctype, f: field });
} }
if (existing) { this.components[ctype.name] = ctype;
existing.fields = ctype.fields; return ctype;
return existing;
} else {
return this.components[ctype.name] = ctype;
}
} }
defineSystem(system: System) { defineSystem(system: System) {
let existing = this.systems[system.name]; let existing = this.systems[system.name];
@ -1669,15 +1670,15 @@ export class EntityManager {
return this.systems[name]; return this.systems[name];
} }
singleComponentWithFieldName(atypes: EntityArchetype[], fieldName: string, where: SourceLocated) { singleComponentWithFieldName(atypes: EntityArchetype[], fieldName: string, where: SourceLocated) {
let components = this.componentsWithFieldName(atypes, fieldName); let cfpairs = this.name2cfpairs[fieldName];
// TODO: use name2cfpairs? let filtered = cfpairs.filter(cf => atypes.find(a => a.components.includes(cf.c)));
if (components.length == 0) { if (filtered.length == 0) {
throw new ECSError(`cannot find component with field "${fieldName}"`, where); throw new ECSError(`cannot find component with field "${fieldName}"`, where);
} }
if (components.length > 1) { if (filtered.length > 1) {
throw new ECSError(`ambiguous field name "${fieldName}"`, where); throw new ECSError(`ambiguous field name "${fieldName}"`, where);
} }
return components[0]; return filtered[0].c;
} }
toJSON() { toJSON() {
return JSON.stringify({ return JSON.stringify({

View File

@ -98,11 +98,19 @@ describe('Compiler', function() {
return readFileSync(testdir + path, 'utf-8'); return readFileSync(testdir + path, 'utf-8');
} }
let code = readFileSync(ecspath, 'utf-8'); let code = readFileSync(ecspath, 'utf-8');
compiler.parseFile(code, ecspath); var outtxt = '';
// TODO: errors try {
let out = new SourceFileExport(); compiler.parseFile(code, ecspath);
em.exportToFile(out); // TODO: errors
let outtxt = out.toString(); let out = new SourceFileExport();
em.exportToFile(out);
outtxt = out.toString();
} catch (e) {
outtxt = e.toString();
console.log(e);
}
if (compiler.errors.length)
outtxt = compiler.errors.map(e => `${e.line}:${e.msg}`).join('\n');
let goodtxt = existsSync(goodpath) ? readFileSync(goodpath, 'utf-8') : ''; let goodtxt = existsSync(goodpath) ? readFileSync(goodpath, 'utf-8') : '';
if (outtxt.trim() != goodtxt.trim()) { if (outtxt.trim() != goodtxt.trim()) {
let asmpath = '/tmp/' + asmfn; let asmpath = '/tmp/' + asmfn;

31
test/ecs/errors1.ecs Normal file
View File

@ -0,0 +1,31 @@
component KernelSection
lines: 1..255
end
component BGColor
color: 0..255
end
component FGColor
color: 0..255
end
demo Main
entity [KernelSection,BGColor]
const lines = 2
const color = $18
end
entity [KernelSection,BGColor,FGColor]
const lines = 2
const color = $16
end
entity [KernelSection,FGColor]
const lines = 2
const color = $16
end
entity [KernelSection,FGColor]
const lines = 2
const color = $16
end
end

1
test/ecs/errors1.txt Normal file
View File

@ -0,0 +1 @@
21:I found more than one field named "color" for this entity.