1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-29 14:51:17 +00:00

ecs: actions have queries

This commit is contained in:
Steven Hugg 2022-01-27 12:43:27 -06:00
parent 4c2442dd90
commit 47461b5a28

View File

@ -54,17 +54,16 @@ export interface Query {
export interface System { export interface System {
name: string; name: string;
actions: CodeFragment[]; actions: Action[];
query: Query;
tempbytes?: number; tempbytes?: number;
emits?: string[]; emits?: string[];
live?: EntityArchetype[] | null;
} }
export interface CodeFragment { export interface Action {
text: string; text: string;
event: string; event: string;
iterate: 'once' | 'each' query: Query;
select: 'once' | 'each' | 'source'
} }
export type DataValue = number | boolean | Uint8Array; export type DataValue = number | boolean | Uint8Array;
@ -421,13 +420,14 @@ export class EntityScope {
this.tempOffset += n; this.tempOffset += n;
this.maxTempBytes = Math.max(this.tempOffset, this.maxTempBytes); this.maxTempBytes = Math.max(this.tempOffset, this.maxTempBytes);
} }
replaceCode(code: string, sys: System, action: CodeFragment): string { replaceCode(code: string, sys: System, action: Action): string {
const re = /\%\{(.+?)\}/g; const re = /\%\{(.+?)\}/g;
let label = sys.name + '_' + action.event; let label = sys.name + '_' + action.event;
let atypes = this.em.archetypesMatching(sys.query); let atypes = this.em.archetypesMatching(action.query);
let entities = this.entitiesMatching(atypes); let entities = this.entitiesMatching(atypes);
// TODO: find loops // TODO: detect cycles
if (action.iterate == 'each') { // TODO: "source"?
if (action.select == 'each') {
code = this.wrapCodeInLoop(code, sys, action, entities); code = this.wrapCodeInLoop(code, sys, action, entities);
//console.log(sys.name, action.event, ents); //console.log(sys.name, action.event, ents);
//frag = this.iterateCode(frag); //frag = this.iterateCode(frag);
@ -460,7 +460,7 @@ export class EntityScope {
this.subroutines.add(symbol); this.subroutines.add(symbol);
return symbol; return symbol;
} }
wrapCodeInLoop(code: string, sys: System, action: CodeFragment, ents: Entity[]): string { wrapCodeInLoop(code: string, sys: System, action: Action, ents: Entity[]): string {
// TODO: check ents // TODO: check ents
// TODO: check segment bounds // TODO: check segment bounds
let s = ASM_ITERATE_EACH; let s = ASM_ITERATE_EACH;
@ -470,7 +470,7 @@ export class EntityScope {
s = s.replace('%{code}', code); s = s.replace('%{code}', code);
return s; return s;
} }
generateCodeForField(sys: System, action: CodeFragment, generateCodeForField(sys: System, action: Action,
atypes: ArchetypeMatch[], entities: Entity[], atypes: ArchetypeMatch[], entities: Entity[],
fieldName: string, bitofs: number): string { fieldName: string, bitofs: number): string {
// find archetypes // find archetypes
@ -513,7 +513,7 @@ export class EntityScope {
systemListensTo(sys: System, events: string[]) { systemListensTo(sys: System, events: string[]) {
for (let action of sys.actions) { for (let action of sys.actions) {
if (action.event != null && events.includes(action.event)) { if (action.event != null && events.includes(action.event)) {
let archs = this.em.archetypesMatching(sys.query); let archs = this.em.archetypesMatching(action.query);
for (let arch of archs) { for (let arch of archs) {
for (let ctype of arch.cmatch) { for (let ctype of arch.cmatch) {
if (this.hasComponent(ctype)) { if (this.hasComponent(ctype)) {
@ -843,39 +843,60 @@ const INITFROMARRAY = `
function test() { function test() {
let em = new EntityManager(); let em = new EntityManager();
let c_kernel = em.defineComponent({name:'kernel', fields:[ let c_kernel = em.defineComponent({
{name:'lines', dtype:'int', lo:0, hi:255} name: 'kernel', fields: [
]}) { name: 'lines', dtype: 'int', lo: 0, hi: 255 },
let c_sprite = em.defineComponent({name:'sprite', fields:[ { name: 'bgcolor', dtype: 'int', lo: 0, hi: 255 },
]
})
let c_sprite = em.defineComponent({
name: 'sprite', fields: [
{ name: 'height', dtype: 'int', lo: 0, hi: 255 }, { name: 'height', dtype: 'int', lo: 0, hi: 255 },
{ name: 'plyrindex', dtype: 'int', lo: 0, hi: 1 }, { name: 'plyrindex', dtype: 'int', lo: 0, hi: 1 },
{ name: 'flags', dtype: 'int', lo: 0, hi: 255 }, { name: 'flags', dtype: 'int', lo: 0, hi: 255 },
]}) ]
let c_player = em.defineComponent({name:'player', fields:[ })
let c_player = em.defineComponent({
name: 'player', fields: [
//TODO: optional? //TODO: optional?
]}) ]
let c_hasbitmap = em.defineComponent({name:'hasbitmap', fields:[ })
let c_hasbitmap = em.defineComponent({
name: 'hasbitmap', fields: [
{ name: 'bitmap', dtype: 'ref', query: { include: ['bitmap'] } }, { name: 'bitmap', dtype: 'ref', query: { include: ['bitmap'] } },
]}) ]
let c_hascolormap = em.defineComponent({name:'hascolormap', fields:[ })
let c_hascolormap = em.defineComponent({
name: 'hascolormap', fields: [
{ name: 'colormap', dtype: 'ref', query: { include: ['colormap'] } }, { name: 'colormap', dtype: 'ref', query: { include: ['colormap'] } },
]}) ]
let c_bitmap = em.defineComponent({name:'bitmap', fields:[ })
let c_bitmap = em.defineComponent({
name: 'bitmap', fields: [
{ name: 'bitmapdata', dtype: 'array', elem: { dtype: 'int', lo: 0, hi: 255 } } { name: 'bitmapdata', dtype: 'array', elem: { dtype: 'int', lo: 0, hi: 255 } }
]}) ]
let c_colormap = em.defineComponent({name:'colormap', fields:[ })
let c_colormap = em.defineComponent({
name: 'colormap', fields: [
{ name: 'colormapdata', dtype: 'array', elem: { dtype: 'int', lo: 0, hi: 255 } } { name: 'colormapdata', dtype: 'array', elem: { dtype: 'int', lo: 0, hi: 255 } }
]}) ]
let c_xpos = em.defineComponent({name:'xpos', fields:[ })
let c_xpos = em.defineComponent({
name: 'xpos', fields: [
{ name: 'xpos', dtype: 'int', lo: 0, hi: 255 } { name: 'xpos', dtype: 'int', lo: 0, hi: 255 }
]}) ]
let c_ypos = em.defineComponent({name:'ypos', fields:[ })
let c_ypos = em.defineComponent({
name: 'ypos', fields: [
{ name: 'ypos', dtype: 'int', lo: 0, hi: 255 } { name: 'ypos', dtype: 'int', lo: 0, hi: 255 }
]}) ]
let c_xyvel = em.defineComponent({name:'xyvel', fields:[ })
let c_xyvel = em.defineComponent({
name: 'xyvel', fields: [
{ name: 'xvel', dtype: 'int', lo: -8, hi: 7 }, { name: 'xvel', dtype: 'int', lo: -8, hi: 7 },
{ name: 'yvel', dtype: 'int', lo: -8, hi: 7 } { name: 'yvel', dtype: 'int', lo: -8, hi: 7 }
]}) ]
})
// init -> [start] -> frameloop // init -> [start] -> frameloop
// frameloop -> [preframe] [kernel] [postframe] // frameloop -> [preframe] [kernel] [postframe]
@ -886,21 +907,27 @@ function test() {
em.defineSystem({ em.defineSystem({
name: 'kernel_simple', name: 'kernel_simple',
tempbytes: 8, tempbytes: 8,
query:{ actions: [
{
text: TEMPLATE4_S, event: 'preframe', select: 'once', query: {
include: ['sprite', 'hasbitmap', 'hascolormap', 'ypos'], include: ['sprite', 'hasbitmap', 'hascolormap', 'ypos'],
}, },
actions:[ },
{ text:TEMPLATE4_S, event:'preframe', iterate:'once' }, {
{ text:TEMPLATE4_K, event:'kernel', iterate:'once' }, text: TEMPLATE4_K, event: 'kernel', select: 'once', query: {
include: ['kernel']
}
},
] ]
}) })
em.defineSystem({ em.defineSystem({
name: 'set_xpos', name: 'set_xpos',
query:{ actions: [
{
text: SET_XPOS, event: 'preframe', select: 'each', query: {
include: ['sprite', 'xpos'] include: ['sprite', 'xpos']
}, },
actions:[ },
{ text:SET_XPOS, event:'preframe', iterate:'each' },
//{ text:SETHORIZPOS }, //{ text:SETHORIZPOS },
] ]
}) })
@ -913,50 +940,37 @@ function test() {
em.defineSystem({ em.defineSystem({
name: 'frameloop', name: 'frameloop',
emits: ['preframe', 'kernel', 'postframe'], emits: ['preframe', 'kernel', 'postframe'],
query:{
include:['kernel'], // ???
},
actions: [ actions: [
{ text:TEMPLATE1, event:'start', iterate:'once' } { text: TEMPLATE1, event: 'start', select: 'once', query: { include: [] } } // TODO: []?
] ]
}) })
em.defineSystem({ em.defineSystem({
name: 'joyread', name: 'joyread',
query:{
include:['player']
},
tempbytes: 1, tempbytes: 1,
emits: ['joyup', 'joydown', 'joyleft', 'joyright', 'joybutton'], emits: ['joyup', 'joydown', 'joyleft', 'joyright', 'joybutton'],
actions: [ actions: [
{ text:TEMPLATE2_a, event:'postframe', iterate:'once' }, { text: TEMPLATE2_a, event: 'postframe', select: 'once', query: { include: ['player'] } },
{ text:TEMPLATE2_b, event:'postframe', iterate:'each' } { text: TEMPLATE2_b, event: 'postframe', select: 'each', query: { include: ['player'] } }
] ]
}); });
em.defineSystem({ em.defineSystem({
name: 'move_x', name: 'move_x',
query:{
include:['player','xpos']
},
actions: [ actions: [
{ text:TEMPLATE3_L, event:'joyleft', iterate:'once' }, // TODO: event source? { text: TEMPLATE3_L, event: 'joyleft', select: 'source', query: { include: ['player', 'xpos'] }, },
{ text:TEMPLATE3_R, event:'joyright', iterate:'once' }, // TODO: event source? { text: TEMPLATE3_R, event: 'joyright', select: 'source', query: { include: ['player', 'xpos'] }, },
] ]
}); });
em.defineSystem({ em.defineSystem({
name: 'move_y', name: 'move_y',
query:{
include:['player','ypos']
},
actions: [ actions: [
{ text:TEMPLATE3_U, event:'joyup', iterate:'once' }, // TODO: event source? { text: TEMPLATE3_U, event: 'joyup', select: 'source', query: { include: ['player', 'ypos'] } },
{ text:TEMPLATE3_D, event:'joydown', iterate:'once' }, // TODO: event source? { text: TEMPLATE3_D, event: 'joydown', select: 'source', query: { include: ['player', 'ypos'] } },
] ]
}); });
em.defineSystem({ em.defineSystem({
name: 'SetHorizPos', name: 'SetHorizPos',
query:{ include:[] }, // TODO?
actions: [ actions: [
{ text:SETHORIZPOS, event:'SetHorizPos', iterate:'once' }, // TODO: event source? { text: SETHORIZPOS, event: 'SetHorizPos', select: 'once', query: { include: [] } }, // TODO: []?
] ]
}); });