flow: dirtiness
This commit is contained in:
parent
94addfb22a
commit
788e94db41
|
@ -51,7 +51,7 @@ class BaseComponent {
|
||||||
return this.$$dirty;
|
return this.$$dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
set dirty(dirty) {
|
setDirty(dirty) {
|
||||||
this.$$dirty = dirty;
|
this.$$dirty = dirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,9 +84,9 @@ class FlatComponent extends BaseComponent {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
count -= results.length;
|
count -= results.length;
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
const required = (this.caret + count) * this.schema.width;
|
const required = (this.caret + count) * this.constructor.width;
|
||||||
if (required > this.data.byteLength) {
|
if (required > this.data.byteLength) {
|
||||||
const chunkWidth = this.chunkSize * this.schema.width;
|
const chunkWidth = this.chunkSize * this.constructor.width;
|
||||||
const remainder = required % chunkWidth;
|
const remainder = required % chunkWidth;
|
||||||
const extra = 0 === remainder ? 0 : chunkWidth - remainder;
|
const extra = 0 === remainder ? 0 : chunkWidth - remainder;
|
||||||
const size = required + extra;
|
const size = required + extra;
|
||||||
|
@ -111,7 +111,7 @@ class FlatComponent extends BaseComponent {
|
||||||
const window = new this.Window(this.data, this);
|
const window = new this.Window(this.data, this);
|
||||||
for (let i = 0; i < this.caret; ++i) {
|
for (let i = 0; i < this.caret; ++i) {
|
||||||
window.dirty = false;
|
window.dirty = false;
|
||||||
window.cursor += this.schema.width;
|
window.cursor += this.constructor.width;
|
||||||
}
|
}
|
||||||
this.dirty = false;
|
this.dirty = false;
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,8 @@ class FlatComponent extends BaseComponent {
|
||||||
entity = entries[i];
|
entity = entries[i];
|
||||||
}
|
}
|
||||||
this.map[entity] = allocated[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) {
|
for (const [i] of this.schema) {
|
||||||
if (i in values) {
|
if (i in values) {
|
||||||
window[i] = values[i];
|
window[i] = values[i];
|
||||||
|
@ -155,7 +156,7 @@ class FlatComponent extends BaseComponent {
|
||||||
this.Window = this.makeWindowClass();
|
this.Window = this.makeWindowClass();
|
||||||
}
|
}
|
||||||
const window = new this.Window(this.data, this);
|
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;
|
return window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +170,7 @@ class FlatComponent extends BaseComponent {
|
||||||
if (!this.window) {
|
if (!this.window) {
|
||||||
this.window = new this.Window(this.data, this);
|
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;
|
return this.window;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,18 +195,23 @@ class FlatComponent extends BaseComponent {
|
||||||
}
|
}
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
const properties = {};
|
const properties = {};
|
||||||
|
const {width} = this.constructor;
|
||||||
const get = (type) => (
|
const get = (type) => (
|
||||||
`return this.view.get${Schema.viewMethodFromType(type)}(this.cursor + ${offset}, true);`
|
`return this.view.get${Schema.viewMethodFromType(type)}(this.cursor + ${offset}, true);`
|
||||||
);
|
);
|
||||||
const set = (type) => [
|
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.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('');
|
].join('');
|
||||||
/* eslint-disable no-new-func */
|
/* eslint-disable no-new-func */
|
||||||
properties.dirty = {
|
properties.dirty = {
|
||||||
get: new Function('', `return !!this.view.getUint8(this.cursor + ${this.schema.width - 1}, true);`),
|
get: new Function('', `return !!this.view.getUint8(this.cursor + ${width - 1}, true);`),
|
||||||
set: new Function('v', `this.view.setUint8(this.cursor + ${this.schema.width - 1}, v ? 1 : 0, 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) {
|
for (const [i, spec] of this.schema) {
|
||||||
const {type} = spec;
|
const {type} = spec;
|
||||||
|
@ -229,7 +235,7 @@ class ArbitraryComponent extends BaseComponent {
|
||||||
|
|
||||||
allocateMany(count) {
|
allocateMany(count) {
|
||||||
if (!this.Instance) {
|
if (!this.Instance) {
|
||||||
this.Instance = this.constructor.instanceFromSchema(this.schema);
|
this.Instance = this.instanceFromSchema();
|
||||||
}
|
}
|
||||||
const results = super.allocateMany(count);
|
const results = super.allocateMany(count);
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
@ -248,7 +254,7 @@ class ArbitraryComponent extends BaseComponent {
|
||||||
for (const i in this.map) {
|
for (const i in this.map) {
|
||||||
this.data[this.map[i]].dirty = false;
|
this.data[this.map[i]].dirty = false;
|
||||||
}
|
}
|
||||||
this.dirty = false;
|
this.setDirty(false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
createMany(entries) {
|
createMany(entries) {
|
||||||
|
@ -264,6 +270,7 @@ class ArbitraryComponent extends BaseComponent {
|
||||||
entity = entries[i];
|
entity = entries[i];
|
||||||
}
|
}
|
||||||
this.map[entity] = allocated[i];
|
this.map[entity] = allocated[i];
|
||||||
|
this.data[allocated[i]].entity = entity;
|
||||||
for (const j in values) {
|
for (const j in values) {
|
||||||
if (this.schema.has(j)) {
|
if (this.schema.has(j)) {
|
||||||
this.data[allocated[i]][j] = values[j];
|
this.data[allocated[i]][j] = values[j];
|
||||||
|
@ -281,12 +288,16 @@ class ArbitraryComponent extends BaseComponent {
|
||||||
return this.get(entity);
|
return this.get(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
static instanceFromSchema(schema) {
|
instanceFromSchema() {
|
||||||
|
const Component = this;
|
||||||
const Instance = class {
|
const Instance = class {
|
||||||
|
|
||||||
|
$$dirty = 1;
|
||||||
|
|
||||||
|
$$entity = 0;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.$$dirty = 1;
|
for (const [i, {defaultValue}] of Component.schema) {
|
||||||
for (const [i, {defaultValue}] of schema) {
|
|
||||||
this[i] = defaultValue;
|
this[i] = defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,7 +312,15 @@ class ArbitraryComponent extends BaseComponent {
|
||||||
this.$$dirty = v;
|
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] = {
|
properties[i] = {
|
||||||
get: function get() {
|
get: function get() {
|
||||||
return this[`$$${i}`];
|
return this[`$$${i}`];
|
||||||
|
@ -309,6 +328,7 @@ class ArbitraryComponent extends BaseComponent {
|
||||||
set: function set(v) {
|
set: function set(v) {
|
||||||
this[`$$${i}`] = v;
|
this[`$$${i}`] = v;
|
||||||
this.$$dirty = 1;
|
this.$$dirty = 1;
|
||||||
|
Component.setDirty(1, this.entity);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -322,10 +342,11 @@ export default function ComponentRouter() {
|
||||||
const schema = new Schema(this.constructor.schema);
|
const schema = new Schema(this.constructor.schema);
|
||||||
let RealClass;
|
let RealClass;
|
||||||
if (schema.width > 0) {
|
if (schema.width > 0) {
|
||||||
RealClass = FlatComponent;
|
RealClass = class extends FlatComponent {};
|
||||||
|
RealClass.width = schema.width + 9; // 1 for dirty, 8 for entity
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
RealClass = ArbitraryComponent;
|
RealClass = class extends ArbitraryComponent {};
|
||||||
}
|
}
|
||||||
return new RealClass(schema);
|
return new RealClass(schema);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,6 @@ export default class Ecs {
|
||||||
|
|
||||||
$$caret = 1;
|
$$caret = 1;
|
||||||
|
|
||||||
$$cleanEntities = new Set();
|
|
||||||
|
|
||||||
Components = {};
|
Components = {};
|
||||||
|
|
||||||
dirty = new Set();
|
dirty = new Set();
|
||||||
|
@ -20,24 +18,15 @@ export default class Ecs {
|
||||||
|
|
||||||
constructor(Components) {
|
constructor(Components) {
|
||||||
for (const i in Components) {
|
for (const i in Components) {
|
||||||
class Component extends Components[i] {
|
const comp = new Components[i]();
|
||||||
|
const {setDirty} = comp;
|
||||||
set dirty(dirty) {
|
comp.setDirty = (dirty, entity) => {
|
||||||
super.dirty = dirty;
|
setDirty.call(comp, dirty);
|
||||||
const it = this.$$cleanEntities.values();
|
if (entity) {
|
||||||
let result = it.next();
|
this.dirty.add(entity);
|
||||||
while (!result.done) {
|
|
||||||
result = it.next();
|
|
||||||
}
|
}
|
||||||
for (let i = 0; i < this.$$entities.length; i++) {
|
};
|
||||||
if (this.get(this.$$entities[i])) {
|
this.Components[i] = comp;
|
||||||
this.dirty.add(this.$$entities[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
this.Components[i] = new Component();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +132,7 @@ export default class Ecs {
|
||||||
for (const i in this.Components) {
|
for (const i in this.Components) {
|
||||||
this.Components[i].clean();
|
this.Components[i].clean();
|
||||||
}
|
}
|
||||||
this.dirty = [];
|
this.dirty.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
tickFinalize() {
|
tickFinalize() {
|
||||||
|
|
|
@ -65,7 +65,9 @@ for (let i = 0; i < warm; ++i) {
|
||||||
}
|
}
|
||||||
performance.mark('tick0');
|
performance.mark('tick0');
|
||||||
ecs.tick(0.01);
|
ecs.tick(0.01);
|
||||||
|
console.log(ecs.dirty.size);
|
||||||
ecs.tickFinalize();
|
ecs.tickFinalize();
|
||||||
|
console.log(ecs.dirty.size);
|
||||||
performance.mark('tick1');
|
performance.mark('tick1');
|
||||||
console.log(ecs.$$systems[0].queries.default.count);
|
console.log(ecs.$$systems[0].queries.default.count);
|
||||||
|
|
||||||
|
@ -78,6 +80,7 @@ console.log({
|
||||||
y: p.y,
|
y: p.y,
|
||||||
z: p.z,
|
z: p.z,
|
||||||
dirty: p.dirty,
|
dirty: p.dirty,
|
||||||
|
entity: p.entity,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(performance.getEntriesByType('measure').map(({duration, name}) => ({duration, name})));
|
console.log(performance.getEntriesByType('measure').map(({duration, name}) => ({duration, name})));
|
||||||
|
|
|
@ -4,7 +4,7 @@ export default class Schema {
|
||||||
|
|
||||||
defaultValues = {};
|
defaultValues = {};
|
||||||
|
|
||||||
width = 1;
|
width = 0;
|
||||||
|
|
||||||
spec;
|
spec;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user