ecs: allocate init data table
This commit is contained in:
parent
ba73d7bb19
commit
44ffa5e988
|
@ -14,6 +14,18 @@
|
|||
// when entering scope, entities are initialized (zero or init w/ data)
|
||||
// to change scope, fire event w/ scope name
|
||||
// - how to handle bank-switching?
|
||||
//
|
||||
// helps with:
|
||||
// - rapid prototyping w/ reasonable defaults
|
||||
// - deconstructing objects into arrays
|
||||
// - packing/unpacking bitfields
|
||||
// - initializing objects
|
||||
// - building lookup tables
|
||||
// - selecting and iterating objects
|
||||
// - managing events
|
||||
// - managing memory and scope
|
||||
// - converting assets to native formats?
|
||||
// - removing unused data
|
||||
|
||||
function mksymbol(c: ComponentType, fieldName: string) {
|
||||
return c.name + '_' + fieldName;
|
||||
|
@ -66,7 +78,7 @@ export interface Action {
|
|||
select: 'once' | 'each' | 'source'
|
||||
}
|
||||
|
||||
export type DataValue = number | boolean | Uint8Array;
|
||||
export type DataValue = number | boolean | Uint8Array | Uint16Array;
|
||||
|
||||
export type DataField = { name: string } & DataType;
|
||||
|
||||
|
@ -121,7 +133,7 @@ class SourceFileExport {
|
|||
}
|
||||
segment(seg: string, segtype: 'rodata' | 'bss') {
|
||||
if (segtype == 'bss') {
|
||||
this.lines.push(`.zeropage`); // TODO
|
||||
this.lines.push(`.segment "ZEROPAGE"`); // TODO
|
||||
} else {
|
||||
this.lines.push(`.segment "CODE"`); // TODO
|
||||
}
|
||||
|
@ -229,13 +241,14 @@ function getPackedFieldSize(f: DataType, constValue?: DataValue): number {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO: language dialects?
|
||||
const ASM_ITERATE_EACH = `
|
||||
ldx #0
|
||||
%{@loop}:
|
||||
%{@__each}:
|
||||
%{code}
|
||||
inx
|
||||
cpx #%{ecount}
|
||||
bne %{@loop}
|
||||
bne %{@__each}
|
||||
`;
|
||||
|
||||
export class EntityScope {
|
||||
|
@ -323,23 +336,30 @@ export class EntityScope {
|
|||
let cfname = mksymbol(c, f.name);
|
||||
let fieldrange = segment.fieldranges[cfname];
|
||||
if (v !== undefined) {
|
||||
let entcount = fieldrange.ehi - fieldrange.elo + 1;
|
||||
// is it a byte array?
|
||||
if (v instanceof Uint8Array) {
|
||||
let datasym = `${c.name}_${f.name}_e${e.id}`;
|
||||
let ptrlosym = `${c.name}_${f.name}_b0`;
|
||||
let ptrhisym = `${c.name}_${f.name}_b8`;
|
||||
let entcount = fieldrange.ehi - fieldrange.elo + 1;
|
||||
segment.allocateInitData(datasym, v);
|
||||
let loofs = segment.allocateBytes(ptrlosym, entcount);
|
||||
let hiofs = segment.allocateBytes(ptrhisym, entcount);
|
||||
segment.initdata[loofs + e.id - fieldrange.elo] = { symbol: datasym, bitofs: 0 };
|
||||
segment.initdata[hiofs + e.id - fieldrange.elo] = { symbol: datasym, bitofs: 8 };
|
||||
} else if (fieldrange.ehi > fieldrange.elo) {
|
||||
// more than one element, add an array
|
||||
// TODO
|
||||
// TODO: } else if (v instanceof Uint16Array) {
|
||||
} else if (typeof v === 'number') {
|
||||
// more than 1 entity, add an array
|
||||
// TODO: what if > 8 bits?
|
||||
// TODO: what if mix of var, const, and init values?
|
||||
if (fieldrange.ehi > fieldrange.elo) {
|
||||
let datasym = `${c.name}_${f.name}_b0`;
|
||||
let base = segment.allocateBytes(datasym, entcount);
|
||||
segment.initdata[base + e.id - fieldrange.elo] = v;
|
||||
}
|
||||
} else {
|
||||
throw new Error(`unhandled constant ${e.id}:${cfname}`);
|
||||
}
|
||||
//console.log(cfname, i, v, fieldrange);
|
||||
//segment.allocateInitData(cfname, );
|
||||
}
|
||||
}
|
||||
//console.log(segment.initdata)
|
||||
|
@ -497,7 +517,13 @@ export class EntityScope {
|
|||
}
|
||||
// TODO: offset > 0?
|
||||
//let range = this.bss.getFieldRange(component, fieldName);
|
||||
return `${component.name}_${fieldName}_b${bitofs},x` // TODO? ,x?
|
||||
if (action.select == 'once') {
|
||||
if (entities.length != 1)
|
||||
throw new Error(`can't choose multiple entities for ${fieldName} with select=once`);
|
||||
return `${component.name}_${fieldName}_b${bitofs}` // TODO? check there's only 1 entity?
|
||||
} else {
|
||||
return `${component.name}_${fieldName}_b${bitofs},x` // TODO? ,x?
|
||||
}
|
||||
}
|
||||
entitiesMatching(atypes: ArchetypeMatch[]) {
|
||||
let result = [];
|
||||
|
@ -721,9 +747,9 @@ const TEMPLATE3_D = `
|
|||
%{@nomove}:
|
||||
`;
|
||||
|
||||
const TEMPLATE4_S = `
|
||||
const TEMPLATE4_S1 = `
|
||||
.macro %{@KernelSetup} ent,ofs
|
||||
lda #192 ; TODO: numlinesgit
|
||||
lda #192 ; TODO: numlines
|
||||
sec
|
||||
sbc ypos_ypos_b0+ent
|
||||
sta %{$5}+ofs
|
||||
|
@ -751,7 +777,8 @@ const TEMPLATE4_S = `
|
|||
lda ypos_ypos_b0+ent
|
||||
sta %{$5}+ofs
|
||||
.endmacro
|
||||
|
||||
`
|
||||
const TEMPLATE4_S2 = `
|
||||
%{@KernelSetup} 0,0
|
||||
%{@KernelSetup} 1,6
|
||||
`
|
||||
|
@ -867,7 +894,7 @@ function test() {
|
|||
name: 'sprite', fields: [
|
||||
{ name: 'height', dtype: 'int', lo: 0, hi: 255 },
|
||||
{ name: 'plyrindex', dtype: 'int', lo: 0, hi: 1 },
|
||||
{ name: 'flags', dtype: 'int', lo: 0, hi: 255 },
|
||||
{ name: 'nusiz', dtype: 'int', lo: 0, hi: 15 },
|
||||
]
|
||||
})
|
||||
let c_player = em.defineComponent({
|
||||
|
@ -915,7 +942,6 @@ function test() {
|
|||
// init -> [start] -> frameloop
|
||||
// frameloop -> [preframe] [kernel] [postframe]
|
||||
|
||||
// TODO: where is kernel numlines?
|
||||
// temp between preframe + frame?
|
||||
// TODO: check names for identifierness
|
||||
em.defineSystem({
|
||||
|
@ -923,7 +949,13 @@ function test() {
|
|||
tempbytes: 8,
|
||||
actions: [
|
||||
{
|
||||
text: TEMPLATE4_S, event: 'preframe', select: 'once', query: {
|
||||
text: TEMPLATE4_S1, event: 'preframe', select: 'once', query: {
|
||||
include: ['kernel']
|
||||
}
|
||||
},
|
||||
{
|
||||
// TODO: should include kernel for numlines
|
||||
text: TEMPLATE4_S2, event: 'preframe', select: 'once', query: {
|
||||
include: ['sprite', 'hasbitmap', 'hascolormap', 'ypos'],
|
||||
},
|
||||
},
|
||||
|
@ -945,17 +977,12 @@ function test() {
|
|||
//{ text:SETHORIZPOS },
|
||||
]
|
||||
})
|
||||
// TODO: how to have subsystems? maybe need Scopes
|
||||
// TODO: easy stagger of system update?
|
||||
// TODO: easy lookup tables
|
||||
// TODO: how to init?
|
||||
|
||||
// https://docs.unity3d.com/Packages/com.unity.entities@0.17/manual/ecs_systems.html
|
||||
em.defineSystem({
|
||||
name: 'frameloop',
|
||||
emits: ['preframe', 'kernel', 'postframe'],
|
||||
actions: [
|
||||
{ text: TEMPLATE1, event: 'start', select: 'once', query: { include: ['kernel'] } } // TODO: []?
|
||||
{ text: TEMPLATE1, event: 'start', select: 'once', query: { include: ['kernel'] } }
|
||||
]
|
||||
})
|
||||
em.defineSystem({
|
||||
|
@ -984,7 +1011,7 @@ function test() {
|
|||
em.defineSystem({
|
||||
name: 'SetHorizPos',
|
||||
actions: [
|
||||
{ text: SETHORIZPOS, event: 'SetHorizPos', select: 'once', query: { include: ['xpos'] } }, // TODO: []?
|
||||
{ text: SETHORIZPOS, event: 'SetHorizPos', select: 'once', query: { include: ['xpos'] } },
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -992,23 +1019,24 @@ function test() {
|
|||
let scene = em.newScope("Scene", root);
|
||||
let e_ekernel = root.newEntity({ components: [c_kernel] });
|
||||
root.setConstValue(e_ekernel, c_kernel, 'lines', 192);
|
||||
root.setConstValue(e_ekernel, c_kernel, 'bgcolor', 0x92);
|
||||
//root.setConstValue(e_ekernel, c_kernel, 'bgcolor', 0x92);
|
||||
root.setInitValue(e_ekernel, c_kernel, 'bgcolor', 0x92);
|
||||
|
||||
let e_bitmap0 = root.newEntity({ components: [c_bitmap] });
|
||||
// TODO: store array sizes?
|
||||
root.setConstValue(e_bitmap0, c_bitmap, 'bitmapdata', new Uint8Array([0, 1, 3, 7, 15, 31, 0]));
|
||||
root.setConstValue(e_bitmap0, c_bitmap, 'bitmapdata', new Uint8Array([1, 1, 3, 7, 15, 31, 63, 127]));
|
||||
|
||||
let e_colormap0 = root.newEntity({ components: [c_colormap] });
|
||||
root.setConstValue(e_colormap0, c_colormap, 'colormapdata', new Uint8Array([0, 3, 6, 9, 12, 14, 0]));
|
||||
root.setConstValue(e_colormap0, c_colormap, 'colormapdata', new Uint8Array([6, 3, 6, 9, 12, 14, 31, 63]));
|
||||
|
||||
let ea_playerSprite = { components: [c_sprite, c_hasbitmap, c_hascolormap, c_xpos, c_ypos, c_player] };
|
||||
let e_player0 = root.newEntity(ea_playerSprite);
|
||||
root.setInitValue(e_player0, c_sprite, 'plyrindex', 0);
|
||||
root.setConstValue(e_player0, c_sprite, 'plyrindex', 0);
|
||||
root.setInitValue(e_player0, c_sprite, 'height', 8);
|
||||
root.setInitValue(e_player0, c_xpos, 'xpos', 50);
|
||||
root.setInitValue(e_player0, c_ypos, 'ypos', 50);
|
||||
let e_player1 = root.newEntity(ea_playerSprite);
|
||||
root.setInitValue(e_player1, c_sprite, 'plyrindex', 1);
|
||||
root.setConstValue(e_player1, c_sprite, 'plyrindex', 1);
|
||||
root.setInitValue(e_player1, c_sprite, 'height', 8);
|
||||
root.setInitValue(e_player1, c_xpos, 'xpos', 100);
|
||||
root.setInitValue(e_player1, c_ypos, 'ypos', 60);
|
||||
|
|
Loading…
Reference in New Issue