ecs: const, multiple sys instances for params

This commit is contained in:
Steven Hugg 2022-02-17 09:48:50 -06:00
parent 0451e8ea33
commit 75f36d95dc
2 changed files with 22 additions and 5 deletions

View File

@ -338,6 +338,7 @@ export class ECSCompiler extends Tokenizer {
if (cmd == 'comment') {
this.expectTokenTypes([ECSTokenType.CodeFragment]);
}
// TODO: need to make these local names, otherwise we get "duplicate name"
if (cmd == 'system') {
let sys = this.annotate(() => this.parseSystem());
this.em.defineSystem(sys);
@ -350,7 +351,13 @@ export class ECSCompiler extends Tokenizer {
parseScopeUsing() {
let instlist = this.parseList(this.parseSystemInstanceRef, ',');
let params = {};
if (this.peekToken().str == 'with') {
this.consumeToken();
params = this.parseSystemInstanceParameters();
}
for (let inst of instlist) {
inst.params = params;
this.currentScope?.newSystemInstance(inst);
}
}
@ -464,10 +471,6 @@ export class ECSCompiler extends Tokenizer {
let system = this.em.getSystemByName(name);
if (!system) this.compileError(`I couldn't find a system named "${name}".`, this.lasttoken.$loc);
let params = {};
if (this.peekToken().str == 'with') {
this.consumeToken();
params = this.parseSystemInstanceParameters();
}
let inst = { system, params, id: 0 };
return inst;
}
@ -475,6 +478,9 @@ export class ECSCompiler extends Tokenizer {
parseSystemInstanceParameters() : SystemInstanceParameters {
let scope = this.currentScope;
if (scope == null) throw new Error();
if (this.peekToken().str == '[') {
return { query: this.parseQuery() };
}
this.expectToken('#');
let entname = this.expectIdent();
this.expectToken('.');

View File

@ -61,6 +61,7 @@ export interface System extends SourceLocated {
}
export interface SystemInstanceParameters {
query?: Query;
refEntity?: Entity;
refField?: ComponentFieldPair;
}
@ -600,6 +601,8 @@ class ActionEval {
this.qr = this.qr.intersection(new EntitySet(scope, rq));
//console.log('with', instance.params, rq, this.qr);
}
} else if (instance.params.query) {
this.qr = this.qr.intersection(new EntitySet(scope, instance.params.query));
}
this.entities = this.qr.entities;
//let query = (this.action as ActionWithQuery).query;
@ -767,10 +770,18 @@ class ActionEval {
}
__data(args: string[]) {
let { component, field, bitofs } = this.parseFieldArgs(args);
if (this.qr.entities.length != 1) throw new ECSError(`data command operates on exactly one entity`); // TODO?
if (this.qr.entities.length != 1) throw new ECSError(`data operates on exactly one entity`, this.action); // TODO?
let eid = this.qr.entities[0].id; // TODO?
return this.dialect.datasymbol(component, field, eid, bitofs);
}
__const(args: string[]) {
let { component, field, bitofs } = this.parseFieldArgs(args);
if (this.qr.entities.length != 1) throw new ECSError(`const operates on exactly one entity`, this.action); // TODO?
let constVal = this.qr.entities[0].consts[mksymbol(component, field.name)];
if (constVal === undefined) throw new ECSError(`field is not constant`, this.action); // TODO?
if (typeof constVal !== 'number') throw new ECSError(`field is not numeric`, this.action); // TODO?
return constVal << bitofs;
}
__index(args: string[]) {
// TODO: check select type and if we actually have an index...
let ident = args[0];