flow+perf: indexing, ticking, flat components, etc.
This commit is contained in:
parent
b5698cd392
commit
51bdda5eb9
|
@ -142,6 +142,7 @@ export default class Component {
|
||||||
for (const key in defaults) {
|
for (const key in defaults) {
|
||||||
this[`$$${key}`] = defaults[key];
|
this[`$$${key}`] = defaults[key];
|
||||||
}
|
}
|
||||||
|
Component.ecs.markChange(this.entity, {[Component.constructor.componentName]: values})
|
||||||
}
|
}
|
||||||
toNet(recipient, data) {
|
toNet(recipient, data) {
|
||||||
return data || Component.constructor.filterDefaults(this);
|
return data || Component.constructor.filterDefaults(this);
|
||||||
|
|
|
@ -19,6 +19,7 @@ export default class Alive extends Component {
|
||||||
this.$$dead = true;
|
this.$$dead = true;
|
||||||
const {Ticking} = ecs.get(this.entity);
|
const {Ticking} = ecs.get(this.entity);
|
||||||
if (Ticking) {
|
if (Ticking) {
|
||||||
|
this.$$death.context.entity = ecs.get(this.entity);
|
||||||
const ticker = this.$$death.ticker();
|
const ticker = this.$$death.ticker();
|
||||||
ecs.addDestructionDependency(this.entity.id, ticker);
|
ecs.addDestructionDependency(this.entity.id, ticker);
|
||||||
Ticking.add(ticker);
|
Ticking.add(ticker);
|
||||||
|
@ -35,7 +36,6 @@ export default class Alive extends Component {
|
||||||
instance.deathScript,
|
instance.deathScript,
|
||||||
{
|
{
|
||||||
ecs: this.ecs,
|
ecs: this.ecs,
|
||||||
entity: this.ecs.get(instance.entity),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if (0 === instance.maxHealth) {
|
if (0 === instance.maxHealth) {
|
||||||
|
|
|
@ -2,11 +2,13 @@ import Component from '@/ecs/component.js';
|
||||||
|
|
||||||
export default class Behaving extends Component {
|
export default class Behaving extends Component {
|
||||||
instanceFromSchema() {
|
instanceFromSchema() {
|
||||||
|
const {ecs} = this;
|
||||||
return class BehavingInstance extends super.instanceFromSchema() {
|
return class BehavingInstance extends super.instanceFromSchema() {
|
||||||
$$routineInstances = {};
|
$$routineInstances = {};
|
||||||
tick(elapsed) {
|
tick(elapsed) {
|
||||||
const routine = this.$$routineInstances[this.currentRoutine];
|
const routine = this.$$routineInstances[this.currentRoutine];
|
||||||
if (routine) {
|
if (routine) {
|
||||||
|
routine.context.entity = ecs.get(this.entity);
|
||||||
routine.tick(elapsed);
|
routine.tick(elapsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,12 +22,7 @@ export default class Behaving extends Component {
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for (const key in instance.routines) {
|
for (const key in instance.routines) {
|
||||||
promises.push(
|
promises.push(
|
||||||
this.ecs.readScript(
|
this.ecs.readScript(instance.routines[key])
|
||||||
instance.routines[key],
|
|
||||||
{
|
|
||||||
entity: this.ecs.get(instance.entity),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.then((script) => {
|
.then((script) => {
|
||||||
instance.$$routineInstances[key] = script;
|
instance.$$routineInstances[key] = script;
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -229,7 +229,7 @@ export default class Collider extends Component {
|
||||||
this.$$aabb = {x0: Infinity, x1: -Infinity, y0: Infinity, y1: -Infinity};
|
this.$$aabb = {x0: Infinity, x1: -Infinity, y0: Infinity, y1: -Infinity};
|
||||||
this.$$aabbs = [];
|
this.$$aabbs = [];
|
||||||
const {bodies} = this;
|
const {bodies} = this;
|
||||||
const {Direction: {direction = 0} = {}} = ecs.get(this.entity);
|
const {Direction: {direction = 0} = {}} = ecs.get(this.entity) || {};
|
||||||
for (const body of bodies) {
|
for (const body of bodies) {
|
||||||
let x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity;
|
let x0 = Infinity, x1 = -Infinity, y0 = Infinity, y1 = -Infinity;
|
||||||
for (const point of transform(body.points, {rotation: direction})) {
|
for (const point of transform(body.points, {rotation: direction})) {
|
||||||
|
|
|
@ -8,7 +8,8 @@ export default class Interactive extends Component {
|
||||||
interact(initiator) {
|
interact(initiator) {
|
||||||
const script = this.$$interact.clone();
|
const script = this.$$interact.clone();
|
||||||
script.context.initiator = initiator;
|
script.context.initiator = initiator;
|
||||||
const {Ticking} = ecs.get(this.entity);
|
script.context.subject = ecs.get(this.entity);
|
||||||
|
const {Ticking} = script.context.subject;
|
||||||
Ticking.add(script.ticker());
|
Ticking.add(script.ticker());
|
||||||
}
|
}
|
||||||
get interacting() {
|
get interacting() {
|
||||||
|
@ -28,7 +29,6 @@ export default class Interactive extends Component {
|
||||||
instance.interactScript,
|
instance.interactScript,
|
||||||
{
|
{
|
||||||
ecs: this.ecs,
|
ecs: this.ecs,
|
||||||
subject: this.ecs.get(instance.entity),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,10 +130,19 @@ export default class Ecs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyDeferredChanges(entityId) {
|
||||||
|
const changes = this.deferredChanges[entityId];
|
||||||
|
delete this.deferredChanges[entityId];
|
||||||
|
for (const components of changes) {
|
||||||
|
this.markChange(entityId, components);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
attach(entityIds) {
|
attach(entityIds) {
|
||||||
for (const entityId of entityIds) {
|
for (const entityId of entityIds) {
|
||||||
this.$$detached.delete(entityId);
|
this.$$detached.delete(entityId);
|
||||||
this.$$reindexing.add(entityId);
|
this.$$reindexing.add(entityId);
|
||||||
|
this.applyDeferredChanges(entityId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +199,7 @@ export default class Ecs {
|
||||||
for (const components of componentsList) {
|
for (const components of componentsList) {
|
||||||
specificsList.push([this.$$caret, components]);
|
specificsList.push([this.$$caret, components]);
|
||||||
this.$$detached.add(this.$$caret);
|
this.$$detached.add(this.$$caret);
|
||||||
|
this.deferredChanges[this.$$caret] = [];
|
||||||
this.$$caret += 1;
|
this.$$caret += 1;
|
||||||
}
|
}
|
||||||
return this.createManySpecific(specificsList);
|
return this.createManySpecific(specificsList);
|
||||||
|
@ -213,8 +223,6 @@ export default class Ecs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entityIds.add(entityId);
|
entityIds.add(entityId);
|
||||||
this.$$reindexing.add(entityId);
|
|
||||||
this.rebuild(entityId, () => componentNames);
|
|
||||||
for (const componentName of componentNames) {
|
for (const componentName of componentNames) {
|
||||||
if (!creating[componentName]) {
|
if (!creating[componentName]) {
|
||||||
creating[componentName] = [];
|
creating[componentName] = [];
|
||||||
|
@ -229,15 +237,13 @@ export default class Ecs {
|
||||||
}
|
}
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
for (let i = 0; i < specificsList.length; i++) {
|
for (let i = 0; i < specificsList.length; i++) {
|
||||||
const [entityId] = specificsList[i];
|
const [entityId, components] = specificsList[i];
|
||||||
|
this.$$reindexing.add(entityId);
|
||||||
|
this.rebuild(entityId, () => Object.keys(components));
|
||||||
if (this.$$detached.has(entityId)) {
|
if (this.$$detached.has(entityId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const changes = this.deferredChanges[entityId];
|
this.applyDeferredChanges(entityId);
|
||||||
delete this.deferredChanges[entityId];
|
|
||||||
for (const components of changes) {
|
|
||||||
this.markChange(entityId, components);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return entityIds;
|
return entityIds;
|
||||||
}
|
}
|
||||||
|
@ -354,7 +360,6 @@ export default class Ecs {
|
||||||
const inserting = {};
|
const inserting = {};
|
||||||
const unique = new Set();
|
const unique = new Set();
|
||||||
for (const [entityId, components] of entities) {
|
for (const [entityId, components] of entities) {
|
||||||
this.rebuild(entityId, (componentNames) => [...new Set(componentNames.concat(Object.keys(components)))]);
|
|
||||||
const diff = {};
|
const diff = {};
|
||||||
for (const componentName in components) {
|
for (const componentName in components) {
|
||||||
if (!inserting[componentName]) {
|
if (!inserting[componentName]) {
|
||||||
|
@ -363,7 +368,6 @@ export default class Ecs {
|
||||||
diff[componentName] = {};
|
diff[componentName] = {};
|
||||||
inserting[componentName].push([entityId, components[componentName]]);
|
inserting[componentName].push([entityId, components[componentName]]);
|
||||||
}
|
}
|
||||||
this.$$reindexing.add(entityId);
|
|
||||||
unique.add(entityId);
|
unique.add(entityId);
|
||||||
this.markChange(entityId, diff);
|
this.markChange(entityId, diff);
|
||||||
}
|
}
|
||||||
|
@ -372,12 +376,13 @@ export default class Ecs {
|
||||||
promises.push(this.Components[componentName].insertMany(inserting[componentName]));
|
promises.push(this.Components[componentName].insertMany(inserting[componentName]));
|
||||||
}
|
}
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
|
for (const [entityId, components] of entities) {
|
||||||
|
this.$$reindexing.add(entityId);
|
||||||
|
this.rebuild(entityId, (componentNames) => [...new Set(componentNames.concat(Object.keys(components)))]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
markChange(entityId, components) {
|
markChange(entityId, components) {
|
||||||
if (this.$$detached.has(entityId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (this.deferredChanges[entityId]) {
|
if (this.deferredChanges[entityId]) {
|
||||||
this.deferredChanges[entityId].push(components);
|
this.deferredChanges[entityId].push(components);
|
||||||
return;
|
return;
|
||||||
|
@ -486,7 +491,6 @@ export default class Ecs {
|
||||||
const removing = {};
|
const removing = {};
|
||||||
const unique = new Set();
|
const unique = new Set();
|
||||||
for (const [entityId, components] of entities) {
|
for (const [entityId, components] of entities) {
|
||||||
this.$$reindexing.add(entityId);
|
|
||||||
unique.add(entityId);
|
unique.add(entityId);
|
||||||
const diff = {};
|
const diff = {};
|
||||||
for (const componentName of components) {
|
for (const componentName of components) {
|
||||||
|
@ -497,11 +501,14 @@ export default class Ecs {
|
||||||
removing[componentName].push(entityId);
|
removing[componentName].push(entityId);
|
||||||
}
|
}
|
||||||
this.markChange(entityId, diff);
|
this.markChange(entityId, diff);
|
||||||
this.rebuild(entityId, (componentNames) => componentNames.filter((type) => !components.includes(type)));
|
|
||||||
}
|
}
|
||||||
for (const componentName in removing) {
|
for (const componentName in removing) {
|
||||||
this.Components[componentName].destroyMany(removing[componentName]);
|
this.Components[componentName].destroyMany(removing[componentName]);
|
||||||
}
|
}
|
||||||
|
for (const [entityId, components] of entities) {
|
||||||
|
this.$$reindexing.add(entityId);
|
||||||
|
this.rebuild(entityId, (componentNames) => componentNames.filter((type) => !components.includes(type)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static serialize(ecs, view) {
|
static serialize(ecs, view) {
|
||||||
|
@ -522,6 +529,22 @@ export default class Ecs {
|
||||||
}
|
}
|
||||||
|
|
||||||
tick(elapsed) {
|
tick(elapsed) {
|
||||||
|
// tick systems
|
||||||
|
for (const systemName in this.Systems) {
|
||||||
|
const System = this.Systems[systemName];
|
||||||
|
if (!System.active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!System.frequency) {
|
||||||
|
System.tick(elapsed);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
System.elapsed += elapsed;
|
||||||
|
while (System.elapsed >= System.frequency) {
|
||||||
|
System.tick(System.frequency);
|
||||||
|
System.elapsed -= System.frequency;
|
||||||
|
}
|
||||||
|
}
|
||||||
// destroy entities
|
// destroy entities
|
||||||
const destroying = new Set();
|
const destroying = new Set();
|
||||||
for (const [entityId, {promises}] of this.$$destructionDependencies) {
|
for (const [entityId, {promises}] of this.$$destructionDependencies) {
|
||||||
|
@ -541,22 +564,6 @@ export default class Ecs {
|
||||||
this.$$deindexing.clear();
|
this.$$deindexing.clear();
|
||||||
this.reindex(this.$$reindexing);
|
this.reindex(this.$$reindexing);
|
||||||
this.$$reindexing.clear();
|
this.$$reindexing.clear();
|
||||||
// tick systems
|
|
||||||
for (const systemName in this.Systems) {
|
|
||||||
const System = this.Systems[systemName];
|
|
||||||
if (!System.active) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!System.frequency) {
|
|
||||||
System.tick(elapsed);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
System.elapsed += elapsed;
|
|
||||||
while (System.elapsed >= System.frequency) {
|
|
||||||
System.tick(System.frequency);
|
|
||||||
System.elapsed -= System.frequency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
|
|
|
@ -210,19 +210,23 @@ test('skips indexing detached entities', async () => {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const {$$index: index} = ecs.system('Indexer').queries.default;
|
const {$$map: map} = ecs.system('Indexer').queries.default;
|
||||||
ecs.system('Indexer').active = true;
|
ecs.system('Indexer').active = true;
|
||||||
const attached = await ecs.create({Empty: {}});
|
const attached = await ecs.create({Empty: {}});
|
||||||
expect(Array.from(index))
|
ecs.tick(0);
|
||||||
|
expect(Array.from(map.keys()))
|
||||||
.to.deep.equal([attached]);
|
.to.deep.equal([attached]);
|
||||||
ecs.destroyMany(new Set([attached]));
|
ecs.destroyMany(new Set([attached]));
|
||||||
expect(Array.from(index))
|
ecs.tick(0);
|
||||||
|
expect(Array.from(map.keys()))
|
||||||
.to.deep.equal([]);
|
.to.deep.equal([]);
|
||||||
const detached = await ecs.createDetached({Empty: {}});
|
const detached = await ecs.createDetached({Empty: {}});
|
||||||
expect(Array.from(index))
|
ecs.tick(0);
|
||||||
|
expect(Array.from(map.keys()))
|
||||||
.to.deep.equal([]);
|
.to.deep.equal([]);
|
||||||
ecs.destroyMany(new Set([detached]));
|
ecs.destroyMany(new Set([detached]));
|
||||||
expect(Array.from(index))
|
ecs.tick(0);
|
||||||
|
expect(Array.from(map.keys()))
|
||||||
.to.deep.equal([]);
|
.to.deep.equal([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -336,11 +340,11 @@ test('applies creation patches', async () => {
|
||||||
.to.equal(64);
|
.to.equal(64);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('applies update patches', () => {
|
test('applies update patches', async () => {
|
||||||
const ecs = new Ecs({Components: {Position}});
|
const ecs = new Ecs({Components: {Position}});
|
||||||
ecs.createSpecific(16, {Position: {x: 64}});
|
await ecs.createSpecific(16, {Position: {x: 64}});
|
||||||
ecs.apply({16: {Position: {x: 128}}});
|
await ecs.apply({16: {Position: {x: 128}}});
|
||||||
expect(Array.from(ecs.entities).length)
|
expect(Object.keys(ecs.$$entities).length)
|
||||||
.to.equal(1);
|
.to.equal(1);
|
||||||
expect(ecs.get(16).Position.x)
|
expect(ecs.get(16).Position.x)
|
||||||
.to.equal(128);
|
.to.equal(128);
|
||||||
|
@ -364,9 +368,9 @@ test('applies component deletion patches', async () => {
|
||||||
.to.deep.equal(['Position']);
|
.to.deep.equal(['Position']);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('calculates entity size', () => {
|
test('calculates entity size', async () => {
|
||||||
const ecs = new Ecs({Components: {Empty, Position}});
|
const ecs = new Ecs({Components: {Empty, Position}});
|
||||||
ecs.createSpecific(1, {Empty: {}, Position: {}});
|
await ecs.createSpecific(1, {Empty: {}, Position: {}});
|
||||||
// ID + # of components + Empty + Position + x + y + z
|
// ID + # of components + Empty + Position + x + y + z
|
||||||
// 4 + 2 + 2 + 4 + 2 + 4 + 4 + 4 + 4 = 30
|
// 4 + 2 + 2 + 4 + 2 + 4 + 4 + 4 + 4 = 30
|
||||||
expect(ecs.get(1).size())
|
expect(ecs.get(1).size())
|
||||||
|
@ -375,8 +379,8 @@ test('calculates entity size', () => {
|
||||||
|
|
||||||
test('serializes and deserializes', async () => {
|
test('serializes and deserializes', async () => {
|
||||||
const ecs = new Ecs({Components: {Empty, Name, Position}});
|
const ecs = new Ecs({Components: {Empty, Name, Position}});
|
||||||
ecs.createSpecific(1, {Empty: {}, Position: {x: 64}});
|
await ecs.createSpecific(1, {Empty: {}, Position: {x: 64}});
|
||||||
ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}});
|
await ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}});
|
||||||
expect(ecs.toJSON())
|
expect(ecs.toJSON())
|
||||||
.to.deep.equal({
|
.to.deep.equal({
|
||||||
entities: {
|
entities: {
|
||||||
|
@ -408,8 +412,8 @@ test('serializes and deserializes', async () => {
|
||||||
|
|
||||||
test('deserializes from compatible ECS', async () => {
|
test('deserializes from compatible ECS', async () => {
|
||||||
const ecs = new Ecs({Components: {Empty, Name, Position}});
|
const ecs = new Ecs({Components: {Empty, Name, Position}});
|
||||||
ecs.createSpecific(1, {Empty: {}, Position: {x: 64}});
|
await ecs.createSpecific(1, {Empty: {}, Position: {x: 64}});
|
||||||
ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}});
|
await ecs.createSpecific(16, {Name: {name: 'foobar'}, Position: {x: 128}});
|
||||||
const view = Ecs.serialize(ecs);
|
const view = Ecs.serialize(ecs);
|
||||||
const deserialized = await Ecs.deserialize(
|
const deserialized = await Ecs.deserialize(
|
||||||
new Ecs({Components: {Empty, Name}}),
|
new Ecs({Components: {Empty, Name}}),
|
||||||
|
|
|
@ -23,6 +23,9 @@ export default class EntityFactory {
|
||||||
static componentNames = sorted;
|
static componentNames = sorted;
|
||||||
constructor(id) {
|
constructor(id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
|
for (const type of sorted) {
|
||||||
|
this[type] = Components[type].get(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
size() {
|
size() {
|
||||||
let size = 0;
|
let size = 0;
|
||||||
|
@ -34,15 +37,6 @@ export default class EntityFactory {
|
||||||
return size + 4 + 2;
|
return size + 4 + 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const properties = {};
|
|
||||||
for (const type of sorted) {
|
|
||||||
properties[type] = {};
|
|
||||||
const get = Components[type].get.bind(Components[type]);
|
|
||||||
properties[type].get = function() {
|
|
||||||
return get(this.id);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Object.defineProperties(Entity.prototype, properties);
|
|
||||||
Entity.prototype.updateAttachments = new Function('update', `
|
Entity.prototype.updateAttachments = new Function('update', `
|
||||||
${
|
${
|
||||||
sorted
|
sorted
|
||||||
|
|
|
@ -54,8 +54,10 @@ export default class MaintainColliderHash extends System {
|
||||||
|
|
||||||
within(query) {
|
within(query) {
|
||||||
const within = new Set();
|
const within = new Set();
|
||||||
for (const id of this.hash.within(query)) {
|
if (this.hash) {
|
||||||
within.add(this.ecs.get(id));
|
for (const id of this.hash.within(query)) {
|
||||||
|
within.add(this.ecs.get(id));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return within;
|
return within;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,8 @@ test('emits particles over time', async () => {
|
||||||
current.onValue(resolve);
|
current.onValue(resolve);
|
||||||
}))
|
}))
|
||||||
.to.deep.include({id: 1});
|
.to.deep.include({id: 1});
|
||||||
expect(ecs.get(1))
|
expect(Array.from(ecs.$$detached))
|
||||||
.to.not.be.undefined;
|
.to.deep.equal([2]);
|
||||||
expect(ecs.get(2))
|
|
||||||
.to.be.undefined;
|
|
||||||
emitter.tick(0.06);
|
emitter.tick(0.06);
|
||||||
expect(await new Promise((resolve) => {
|
expect(await new Promise((resolve) => {
|
||||||
current.onValue(resolve);
|
current.onValue(resolve);
|
||||||
|
@ -47,6 +45,6 @@ test('emits particles over time', async () => {
|
||||||
current.onValue(resolve);
|
current.onValue(resolve);
|
||||||
}))
|
}))
|
||||||
.to.deep.include({id: 2});
|
.to.deep.include({id: 2});
|
||||||
expect(ecs.get(2))
|
expect(Array.from(ecs.$$detached))
|
||||||
.to.not.be.undefined;
|
.to.deep.equal([]);
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,8 +28,6 @@ addEventListener('message', (particle) => {
|
||||||
.onEnd(() => {});
|
.onEnd(() => {});
|
||||||
});
|
});
|
||||||
|
|
||||||
const memory = new Set();
|
|
||||||
|
|
||||||
let last = performance.now();
|
let last = performance.now();
|
||||||
function tick(now) {
|
function tick(now) {
|
||||||
const elapsed = (now - last) / 1000;
|
const elapsed = (now - last) / 1000;
|
||||||
|
@ -40,25 +38,11 @@ function tick(now) {
|
||||||
}
|
}
|
||||||
ecs.tick(elapsed);
|
ecs.tick(elapsed);
|
||||||
emitter.tick(elapsed);
|
emitter.tick(elapsed);
|
||||||
const update = {};
|
if ('1' in ecs.diff) {
|
||||||
for (const id in ecs.diff) {
|
delete ecs.diff['1'];
|
||||||
if (false === ecs.diff[id]) {
|
|
||||||
memory.delete(id);
|
|
||||||
update[id] = false;
|
|
||||||
}
|
|
||||||
else if (!memory.has(id)) {
|
|
||||||
update[id] = ecs.$$entities[id].toJSON();
|
|
||||||
}
|
|
||||||
else if (ecs.diff[id]) {
|
|
||||||
update[id] = ecs.diff[id];
|
|
||||||
}
|
|
||||||
memory.add(id);
|
|
||||||
}
|
}
|
||||||
if ('1' in update) {
|
if (Object.keys(ecs.diff).length > 0) {
|
||||||
delete update['1'];
|
postMessage(ecs.diff);
|
||||||
}
|
|
||||||
if (Object.keys(update).length > 0) {
|
|
||||||
postMessage(update);
|
|
||||||
}
|
}
|
||||||
ecs.setClean();
|
ecs.setClean();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user