1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-01 20:41:36 +00:00

ecs: resources

This commit is contained in:
Steven Hugg 2022-01-31 12:11:50 -06:00
parent 87eb8e2f05
commit ec73e41f8c
3 changed files with 43 additions and 12 deletions

View File

@ -49,7 +49,7 @@ export class ECSCompiler extends Tokenizer {
parseTopLevel() {
//this.skipBlankLines();
let tok = this.expectTokens(['component', 'system', 'scope', 'comment']);
let tok = this.expectTokens(['component', 'system', 'scope', 'resource', 'comment']);
if (tok.str == 'component') {
return this.em.defineComponent(this.parseComponentDefinition());
}
@ -59,6 +59,9 @@ export class ECSCompiler extends Tokenizer {
if (tok.str == 'scope') {
return this.parseScope();
}
if (tok.str == 'resource') {
return this.em.defineSystem(this.parseResource());
}
if (tok.str == 'comment') {
this.expectTokenTypes([TokenType.CodeFragment]);
return;
@ -94,9 +97,13 @@ export class ECSCompiler extends Tokenizer {
return { dtype: 'ref', query: this.parseQuery() } as RefType;
}
if (this.peekToken().str == 'array') {
let range : IntType;
this.expectToken('array');
if (this.peekToken().type == ECSTokenType.Integer) {
range = this.parseDataType() as IntType;
}
this.expectToken('of');
return { dtype: 'array', elem: this.parseDataType() } as ArrayType;
return { dtype: 'array', range, elem: this.parseDataType() } as ArrayType;
}
this.compileError(`Unknown data type`); // TODO
}
@ -159,6 +166,20 @@ export class ECSCompiler extends Tokenizer {
return system;
}
parseResource(): System {
let name = this.expectIdent().str;
let query = this.parseQuery();
let tempbytes;
if (this.peekToken().str == 'locals') {
this.consumeToken();
tempbytes = this.expectInteger();
}
let text = this.parseCode();
let select : SelectType = 'once';
let action : Action = { text, event: name, query, select };
return { name, tempbytes, actions: [action] };
}
parseAction(): Action {
// TODO: unused events?
let event = this.expectIdent().str;

View File

@ -155,6 +155,7 @@ interface ComponentFieldPair {
}
export class Dialect_CA65 {
readonly ASM_ITERATE_EACH = `
ldx #0
@__each:
@ -212,6 +213,12 @@ Start:
datasymbol(component: ComponentType, field: DataField, eid: number) {
return `${component.name}_${field.name}_e${eid}`;
}
code() {
return `.code\n`;
}
bss() {
return `.bss\n`;
}
}
// TODO: merge with Dialect?
@ -350,7 +357,7 @@ export class EntityScope implements SourceLocated {
tempOffset = 0;
tempSize = 0;
maxTempBytes = 0;
subroutines = new Set<string>();
resources = new Set<string>();
constructor(
public readonly em: EntityManager,
@ -505,6 +512,7 @@ export class EntityScope implements SourceLocated {
//console.log(segment.initdata)
}
allocateInitData(segment: Segment) {
if (segment.size == 0) return ''; // TODO: warning for no init data?
let initbytes = new Uint8Array(segment.size);
let iter = this.iterateEntityFields(this.entities);
for (var o = iter.next(); o.value; o = iter.next()) {
@ -551,9 +559,11 @@ export class EntityScope implements SourceLocated {
// and have entities in this scope
let systems = this.em.event2system[event];
if (!systems || systems.length == 0) {
console.log(`; warning: no system responds to ${event}`); // TODO: warning
// TODO: error or warning?
console.log(`warning: no system responds to "${event}"`); return '';
//throw new ECSError(`warning: no system responds to "${event}"`);
}
let s = '';
let s = this.dialect.code();
//s += `\n; event ${event}\n`;
let emitcode: { [event: string]: string } = {};
for (let sys of systems) {
@ -594,7 +604,7 @@ export class EntityScope implements SourceLocated {
const tag_re = /\{\{(.+?)\}\}/g;
const label_re = /@(\w+)\b/g;
let label = `${sys.name}__${action.event}`;
let label = `${sys.name}__${action.event}`; // TODO: better label that won't conflict (seq?)
let atypes = this.em.archetypesMatching(action.query);
let entities = this.entitiesMatching(atypes);
// TODO: detect cycles
@ -647,8 +657,8 @@ export class EntityScope implements SourceLocated {
return this.generateCodeForField(sys, action, atypes, entities, rest, 0);
case '>': // high byte
return this.generateCodeForField(sys, action, atypes, entities, rest, 8);
case '^': // subroutine reference
return this.includeSubroutine(rest);
case '^': // resource reference
return this.includeResource(rest);
default:
let value = props[group];
if (value) return value;
@ -657,8 +667,8 @@ export class EntityScope implements SourceLocated {
});
return code;
}
includeSubroutine(symbol: string): string {
this.subroutines.add(symbol);
includeResource(symbol: string): string {
this.resources.add(symbol);
return symbol;
}
wrapCodeInLoop(code: string, action: Action, ents: Entity[], joinfield?: ComponentFieldPair): string {
@ -742,7 +752,7 @@ export class EntityScope implements SourceLocated {
this.code.addCodeFragment(initcode);
let start = this.generateCodeForEvent('start');
this.code.addCodeFragment(start);
for (let sub of Array.from(this.subroutines.values())) {
for (let sub of Array.from(this.resources.values())) {
let code = this.generateCodeForEvent(sub);
this.code.addCodeFragment(code);
}

View File

@ -208,7 +208,7 @@ export class SourceEditor implements ProjectView {
if (!info.path || this.path.endsWith(info.path)) {
var numLines = this.editor.lineCount();
var line = info.line-1;
if (line < 0 || line >= numLines) line = 0;
if (isNaN(line) || line < 0 || line >= numLines) line = 0;
this.addErrorMarker(line, info.msg);
if (info.start != null) {
var markOpts = {className:"mark-error", inclusiveLeft:true};