flow: dirtiness

This commit is contained in:
cha0s 2022-09-14 05:03:08 -05:00
parent 94addfb22a
commit 788e94db41
4 changed files with 53 additions and 40 deletions

View File

@ -51,7 +51,7 @@ class BaseComponent {
return this.$$dirty;
}
set dirty(dirty) {
setDirty(dirty) {
this.$$dirty = dirty;
}
@ -84,9 +84,9 @@ class FlatComponent extends BaseComponent {
// eslint-disable-next-line no-param-reassign
count -= results.length;
if (count > 0) {
const required = (this.caret + count) * this.schema.width;
const required = (this.caret + count) * this.constructor.width;
if (required > this.data.byteLength) {
const chunkWidth = this.chunkSize * this.schema.width;
const chunkWidth = this.chunkSize * this.constructor.width;
const remainder = required % chunkWidth;
const extra = 0 === remainder ? 0 : chunkWidth - remainder;
const size = required + extra;
@ -111,7 +111,7 @@ class FlatComponent extends BaseComponent {
const window = new this.Window(this.data, this);
for (let i = 0; i < this.caret; ++i) {
window.dirty = false;
window.cursor += this.schema.width;
window.cursor += this.constructor.width;
}
this.dirty = false;
}
@ -134,7 +134,8 @@ class FlatComponent extends BaseComponent {
entity = entries[i];
}
this.map[entity] = allocated[i];
window.cursor = allocated[i] * this.schema.width;
window.cursor = allocated[i] * this.constructor.width;
window.entity = entity;
for (const [i] of this.schema) {
if (i in values) {
window[i] = values[i];
@ -155,7 +156,7 @@ class FlatComponent extends BaseComponent {
this.Window = this.makeWindowClass();
}
const window = new this.Window(this.data, this);
window.cursor = this.map[entity] * this.schema.width;
window.cursor = this.map[entity] * this.constructor.width;
return window;
}
@ -169,7 +170,7 @@ class FlatComponent extends BaseComponent {
if (!this.window) {
this.window = new this.Window(this.data, this);
}
this.window.cursor = this.map[entity] * this.schema.width;
this.window.cursor = this.map[entity] * this.constructor.width;
return this.window;
}
@ -194,18 +195,23 @@ class FlatComponent extends BaseComponent {
}
let offset = 0;
const properties = {};
const {width} = this.constructor;
const get = (type) => (
`return this.view.get${Schema.viewMethodFromType(type)}(this.cursor + ${offset}, true);`
);
const set = (type) => [
'this.parent.dirty = true;',
`this.parent.setDirty(1, this.view.getBigUint64(this.cursor + ${width - 9}, true));`,
`this.view.set${Schema.viewMethodFromType(type)}(this.cursor + ${offset}, v, true);`,
`this.view.setUint8(this.cursor + ${this.schema.width - 1}, 1, true);`,
`this.view.setUint8(this.cursor + ${width - 1}, 1, true);`,
].join('');
/* eslint-disable no-new-func */
properties.dirty = {
get: new Function('', `return !!this.view.getUint8(this.cursor + ${this.schema.width - 1}, true);`),
set: new Function('v', `this.view.setUint8(this.cursor + ${this.schema.width - 1}, v ? 1 : 0, true);`),
get: new Function('', `return !!this.view.getUint8(this.cursor + ${width - 1}, true);`),
set: new Function('v', `this.view.setUint8(this.cursor + ${width - 1}, v ? 1 : 0, true);`),
};
properties.entity = {
get: new Function('', `return this.view.getBigUint64(this.cursor + ${width - 9}, true);`),
set: new Function('v', `this.view.setBigUint64(this.cursor + ${width - 9}, v ? 1 : 0, true);`),
};
for (const [i, spec] of this.schema) {
const {type} = spec;
@ -229,7 +235,7 @@ class ArbitraryComponent extends BaseComponent {
allocateMany(count) {
if (!this.Instance) {
this.Instance = this.constructor.instanceFromSchema(this.schema);
this.Instance = this.instanceFromSchema();
}
const results = super.allocateMany(count);
// eslint-disable-next-line no-param-reassign
@ -248,7 +254,7 @@ class ArbitraryComponent extends BaseComponent {
for (const i in this.map) {
this.data[this.map[i]].dirty = false;
}
this.dirty = false;
this.setDirty(false, 0);
}
createMany(entries) {
@ -264,6 +270,7 @@ class ArbitraryComponent extends BaseComponent {
entity = entries[i];
}
this.map[entity] = allocated[i];
this.data[allocated[i]].entity = entity;
for (const j in values) {
if (this.schema.has(j)) {
this.data[allocated[i]][j] = values[j];
@ -281,12 +288,16 @@ class ArbitraryComponent extends BaseComponent {
return this.get(entity);
}
static instanceFromSchema(schema) {
instanceFromSchema() {
const Component = this;
const Instance = class {
$$dirty = 1;
$$entity = 0;
constructor() {
this.$$dirty = 1;
for (const [i, {defaultValue}] of schema) {
for (const [i, {defaultValue}] of Component.schema) {
this[i] = defaultValue;
}
}
@ -301,7 +312,15 @@ class ArbitraryComponent extends BaseComponent {
this.$$dirty = v;
},
};
for (const [i] of schema) {
properties.entity = {
get: function get() {
return this.$$entity;
},
set: function set(v) {
this.$$entity = v;
},
};
for (const [i] of Component.schema) {
properties[i] = {
get: function get() {
return this[`$$${i}`];
@ -309,6 +328,7 @@ class ArbitraryComponent extends BaseComponent {
set: function set(v) {
this[`$$${i}`] = v;
this.$$dirty = 1;
Component.setDirty(1, this.entity);
},
};
}
@ -322,10 +342,11 @@ export default function ComponentRouter() {
const schema = new Schema(this.constructor.schema);
let RealClass;
if (schema.width > 0) {
RealClass = FlatComponent;
RealClass = class extends FlatComponent {};
RealClass.width = schema.width + 9; // 1 for dirty, 8 for entity
}
else {
RealClass = ArbitraryComponent;
RealClass = class extends ArbitraryComponent {};
}
return new RealClass(schema);
}

View File

@ -6,8 +6,6 @@ export default class Ecs {
$$caret = 1;
$$cleanEntities = new Set();
Components = {};
dirty = new Set();
@ -20,24 +18,15 @@ export default class Ecs {
constructor(Components) {
for (const i in Components) {
class Component extends Components[i] {
set dirty(dirty) {
super.dirty = dirty;
const it = this.$$cleanEntities.values();
let result = it.next();
while (!result.done) {
result = it.next();
}
for (let i = 0; i < this.$$entities.length; i++) {
if (this.get(this.$$entities[i])) {
this.dirty.add(this.$$entities[i]);
}
}
const comp = new Components[i]();
const {setDirty} = comp;
comp.setDirty = (dirty, entity) => {
setDirty.call(comp, dirty);
if (entity) {
this.dirty.add(entity);
}
}
this.Components[i] = new Component();
};
this.Components[i] = comp;
}
}
@ -143,7 +132,7 @@ export default class Ecs {
for (const i in this.Components) {
this.Components[i].clean();
}
this.dirty = [];
this.dirty.clear();
}
tickFinalize() {

View File

@ -65,7 +65,9 @@ for (let i = 0; i < warm; ++i) {
}
performance.mark('tick0');
ecs.tick(0.01);
console.log(ecs.dirty.size);
ecs.tickFinalize();
console.log(ecs.dirty.size);
performance.mark('tick1');
console.log(ecs.$$systems[0].queries.default.count);
@ -78,6 +80,7 @@ console.log({
y: p.y,
z: p.z,
dirty: p.dirty,
entity: p.entity,
});
console.log(performance.getEntriesByType('measure').map(({duration, name}) => ({duration, name})));

View File

@ -4,7 +4,7 @@ export default class Schema {
defaultValues = {};
width = 1;
width = 0;
spec;