1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-25 18:33:11 +00:00

ecs: don't need archetypematch?

This commit is contained in:
Steven Hugg 2022-02-06 11:27:08 -06:00
parent d986cda3b3
commit e3d54b9150
2 changed files with 17 additions and 22 deletions

View File

@ -369,7 +369,7 @@ export class ECSCompiler extends Tokenizer {
setEntityProperty(e: Entity, name: string, cmd: 'init' | 'const', valuefn: (field: DataField) => DataValue) { setEntityProperty(e: Entity, name: string, cmd: 'init' | 'const', valuefn: (field: DataField) => DataValue) {
if (!this.currentScope) { this.internalError(); throw new Error(); } if (!this.currentScope) { this.internalError(); throw new Error(); }
let comps = this.em.componentsWithFieldName([{etype: e.etype, cmatch:e.etype.components}], name); let comps = this.em.componentsWithFieldName([e.etype], name);
if (comps.length == 0) this.compileError(`I couldn't find a field named "${name}" for this entity.`) if (comps.length == 0) this.compileError(`I couldn't find a field named "${name}" for this entity.`)
if (comps.length > 1) this.compileError(`I found more than one field named "${name}" for this entity.`) if (comps.length > 1) this.compileError(`I found more than one field named "${name}" for this entity.`)
let field = comps[0].fields.find(f => f.name == name); let field = comps[0].fields.find(f => f.name == name);

View File

@ -182,11 +182,6 @@ interface ConstByte {
bitofs: number; bitofs: number;
} }
interface ArchetypeMatch {
etype: EntityArchetype;
cmatch: ComponentType[];
}
interface ComponentFieldPair { interface ComponentFieldPair {
c: ComponentType; c: ComponentType;
f: DataField; f: DataField;
@ -466,11 +461,11 @@ function getPackedFieldSize(f: DataType, constValue?: DataValue): number {
} }
class EntitySet { class EntitySet {
atypes: ArchetypeMatch[]; atypes: EntityArchetype[];
entities: Entity[]; entities: Entity[];
scope; scope;
constructor(scope: EntityScope, query?: Query, a?: ArchetypeMatch[], e?: Entity[]) { constructor(scope: EntityScope, query?: Query, a?: EntityArchetype[], e?: Entity[]) {
this.scope = scope; this.scope = scope;
if (query) { if (query) {
this.atypes = scope.em.archetypesMatching(query); this.atypes = scope.em.archetypesMatching(query);
@ -489,7 +484,7 @@ class EntitySet {
} }
intersection(qr: EntitySet) { intersection(qr: EntitySet) {
let ents = this.entities.filter(e => qr.entities.includes(e)); let ents = this.entities.filter(e => qr.entities.includes(e));
let atypes = this.atypes.filter(a1 => qr.atypes.find(a2 => a2.etype == a1.etype)); let atypes = this.atypes.filter(a1 => qr.atypes.find(a2 => a2 == a1));
return new EntitySet(this.scope, undefined, atypes, ents); return new EntitySet(this.scope, undefined, atypes, ents);
} }
isContiguous() { isContiguous() {
@ -799,7 +794,7 @@ class ActionEval {
throw new ECSError(`cannot find "${component.name}:${field.name}" in state`, action); throw new ECSError(`cannot find "${component.name}:${field.name}" in state`, action);
} }
} }
getJoinField(action: Action, atypes: ArchetypeMatch[], jtypes: ArchetypeMatch[]): ComponentFieldPair { getJoinField(action: Action, atypes: EntityArchetype[], jtypes: EntityArchetype[]): ComponentFieldPair {
let refs = Array.from(this.scope.iterateArchetypeFields(atypes, (c, f) => f.dtype == 'ref')); let refs = Array.from(this.scope.iterateArchetypeFields(atypes, (c, f) => f.dtype == 'ref'));
// TODO: better error message // TODO: better error message
if (refs.length == 0) throw new ECSError(`cannot find join fields`, action); if (refs.length == 0) throw new ECSError(`cannot find join fields`, action);
@ -874,10 +869,10 @@ export class EntityScope implements SourceLocated {
} }
} }
} }
*iterateArchetypeFields(arch: ArchetypeMatch[], filter?: (c: ComponentType, f: DataField) => boolean) { *iterateArchetypeFields(arch: EntityArchetype[], filter?: (c: ComponentType, f: DataField) => boolean) {
for (let i = 0; i < arch.length; i++) { for (let i = 0; i < arch.length; i++) {
let a = arch[i]; let a = arch[i];
for (let c of a.etype.components) { for (let c of a.components) {
for (let f of c.fields) { for (let f of c.fields) {
if (!filter || filter(c, f)) if (!filter || filter(c, f))
yield { i, c, f }; yield { i, c, f };
@ -885,13 +880,13 @@ export class EntityScope implements SourceLocated {
} }
} }
} }
entitiesMatching(atypes: ArchetypeMatch[]) { entitiesMatching(atypes: EntityArchetype[]) {
let result: Entity[] = []; let result: Entity[] = [];
for (let e of this.entities) { for (let e of this.entities) {
for (let a of atypes) { for (let a of atypes) {
// TODO: what about subclasses? // TODO: what about subclasses?
// TODO: very scary identity ocmpare // TODO: very scary identity ocmpare
if (e.etype === a.etype) { if (e.etype === a) {
result.push(e); result.push(e);
break; break;
} }
@ -1043,12 +1038,12 @@ export class EntityScope implements SourceLocated {
} }
// TODO: check type/range of value // TODO: check type/range of value
setConstValue(e: Entity, component: ComponentType, fieldName: string, value: DataValue) { setConstValue(e: Entity, component: ComponentType, fieldName: string, value: DataValue) {
let c = this.em.singleComponentWithFieldName([{ etype: e.etype, cmatch: [component] }], fieldName, e); let c = this.em.singleComponentWithFieldName([e.etype], fieldName, e);
e.consts[mksymbol(component, fieldName)] = value; e.consts[mksymbol(component, fieldName)] = value;
this.fieldtypes[mksymbol(component, fieldName)] = 'const'; this.fieldtypes[mksymbol(component, fieldName)] = 'const';
} }
setInitValue(e: Entity, component: ComponentType, fieldName: string, value: DataValue) { setInitValue(e: Entity, component: ComponentType, fieldName: string, value: DataValue) {
let c = this.em.singleComponentWithFieldName([{ etype: e.etype, cmatch: [component] }], fieldName, e); let c = this.em.singleComponentWithFieldName([e.etype], fieldName, e);
e.inits[mkscopesymbol(this, component, fieldName)] = value; e.inits[mkscopesymbol(this, component, fieldName)] = value;
this.fieldtypes[mksymbol(component, fieldName)] = 'init'; this.fieldtypes[mksymbol(component, fieldName)] = 'init';
} }
@ -1209,20 +1204,20 @@ export class EntityManager {
return list.length == q.include.length ? list : []; return list.length == q.include.length ? list : [];
} }
archetypesMatching(q: Query) { archetypesMatching(q: Query) {
let result: ArchetypeMatch[] = []; let result = new Set<EntityArchetype>();
for (let etype of Object.values(this.archetypes)) { for (let etype of Object.values(this.archetypes)) {
let cmatch = this.componentsMatching(q, etype); let cmatch = this.componentsMatching(q, etype);
if (cmatch.length > 0) { if (cmatch.length > 0) {
result.push({ etype, cmatch }); result.add(etype);
} }
} }
return result; return Array.from(result.values());
} }
componentsWithFieldName(atypes: ArchetypeMatch[], fieldName: string) { componentsWithFieldName(atypes: EntityArchetype[], fieldName: string) {
// TODO??? // TODO???
let comps = new Set<ComponentType>(); let comps = new Set<ComponentType>();
for (let at of atypes) { for (let at of atypes) {
for (let c of at.cmatch) { for (let c of at.components) {
for (let f of c.fields) { for (let f of c.fields) {
if (f.name == fieldName) if (f.name == fieldName)
comps.add(c); comps.add(c);
@ -1237,7 +1232,7 @@ export class EntityManager {
getSystemByName(name: string): System { getSystemByName(name: string): System {
return this.systems[name]; return this.systems[name];
} }
singleComponentWithFieldName(atypes: ArchetypeMatch[], fieldName: string, where: SourceLocated) { singleComponentWithFieldName(atypes: EntityArchetype[], fieldName: string, where: SourceLocated) {
let components = this.componentsWithFieldName(atypes, fieldName); let components = this.componentsWithFieldName(atypes, fieldName);
// TODO: use name2cfpairs? // TODO: use name2cfpairs?
if (components.length == 0) { if (components.length == 0) {