refactor: queries
This commit is contained in:
parent
219f796570
commit
559d77c92c
|
@ -14,7 +14,7 @@ export default class ApplyControlMovement extends System {
|
|||
};
|
||||
}
|
||||
tick() {
|
||||
for (const [Controlled, Forces, Speed] of this.select('default')) {
|
||||
for (const {Controlled, Forces, Speed} of this.select('default')) {
|
||||
if (!Controlled.locked) {
|
||||
Forces.impulseX += Speed.speed * (Controlled.moveRight - Controlled.moveLeft);
|
||||
Forces.impulseY += Speed.speed * (Controlled.moveDown - Controlled.moveUp);
|
||||
|
|
|
@ -9,9 +9,9 @@ export default class ApplyForces extends System {
|
|||
}
|
||||
|
||||
tick(elapsed) {
|
||||
for (const [Position, Forces] of this.select('default')) {
|
||||
Position.x += elapsed * Forces.impulseX;
|
||||
Position.y += elapsed * Forces.impulseY;
|
||||
for (const {Position, Forces} of this.select('default')) {
|
||||
Position.x += elapsed * (Forces.impulseX + Forces.forceX);
|
||||
Position.y += elapsed * (Forces.impulseY + Forces.forceY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,12 @@ import {System} from '@/ecs/index.js';
|
|||
|
||||
export default class CalculateAabbs extends System {
|
||||
|
||||
static get priority() {
|
||||
return {
|
||||
after: 'ApplyForces',
|
||||
};
|
||||
}
|
||||
|
||||
tick() {
|
||||
for (const {Position: {x, y}, VisibleAabb} of this.ecs.changed(['Position'])) {
|
||||
if (VisibleAabb) {
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import {RESOLUTION} from '@/constants.js'
|
||||
import {System} from '@/ecs/index.js';
|
||||
|
||||
const [hx, hy] = [RESOLUTION.x / 2, RESOLUTION.y / 2];
|
||||
|
||||
export default class FollowCamera extends System {
|
||||
|
||||
static queries() {
|
||||
|
@ -19,8 +16,8 @@ export default class FollowCamera extends System {
|
|||
}
|
||||
|
||||
tick(elapsed) {
|
||||
for (const [, , entityId] of this.select('default')) {
|
||||
this.updateCamera(elapsed * 3, this.ecs.get(entityId));
|
||||
for (const {id} of this.select('default')) {
|
||||
this.updateCamera(elapsed * 3, this.ecs.get(id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ import {System} from '@/ecs/index.js';
|
|||
export default class ResetForces extends System {
|
||||
|
||||
static get priority() {
|
||||
return {phase: 'pre'};
|
||||
return {phase: 'post'};
|
||||
}
|
||||
|
||||
static queries() {
|
||||
|
@ -13,7 +13,7 @@ export default class ResetForces extends System {
|
|||
}
|
||||
|
||||
tick() {
|
||||
for (const [Forces] of this.select('default')) {
|
||||
for (const {Forces} of this.select('default')) {
|
||||
Forces.impulseX = 0;
|
||||
Forces.impulseY = 0;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ export default class ControlMovement extends System {
|
|||
}
|
||||
|
||||
tick(elapsed) {
|
||||
for (const [Sprite] of this.select('default')) {
|
||||
for (const {Sprite} of this.select('default')) {
|
||||
Sprite.elapsed += elapsed / Sprite.speed;
|
||||
while (Sprite.elapsed > 1) {
|
||||
Sprite.elapsed -= 1;
|
||||
|
|
|
@ -15,7 +15,7 @@ export default class RunTickingPromises extends System {
|
|||
}
|
||||
|
||||
tick(elapsed) {
|
||||
for (const [Ticking] of this.select('default')) {
|
||||
for (const {Ticking} of this.select('default')) {
|
||||
if (Ticking.isTicking) {
|
||||
Ticking.tick(elapsed);
|
||||
}
|
||||
|
|
|
@ -9,11 +9,10 @@ export default class SpriteDirection extends System {
|
|||
}
|
||||
|
||||
tick() {
|
||||
for (const [Sprite, entityId] of this.select('default')) {
|
||||
const entity = this.ecs.get(entityId);
|
||||
for (const {Controlled, Direction, Sprite} of this.select('default')) {
|
||||
const parts = [];
|
||||
if (entity.Controlled) {
|
||||
const {locked, moveUp, moveRight, moveDown, moveLeft} = entity.Controlled;
|
||||
if (Controlled) {
|
||||
const {locked, moveUp, moveRight, moveDown, moveLeft} = Controlled;
|
||||
if (locked) {
|
||||
continue;
|
||||
}
|
||||
|
@ -24,14 +23,14 @@ export default class SpriteDirection extends System {
|
|||
parts.push('idle');
|
||||
}
|
||||
}
|
||||
if (entity.Direction) {
|
||||
if (Direction) {
|
||||
const name = {
|
||||
0: 'up',
|
||||
1: 'right',
|
||||
2: 'down',
|
||||
3: 'left',
|
||||
};
|
||||
parts.push(name[entity.Direction.direction]);
|
||||
parts.push(name[Direction.direction]);
|
||||
}
|
||||
if (parts.length > 0) {
|
||||
Sprite.animation = parts.join(':');
|
||||
|
|
|
@ -54,6 +54,12 @@ class SpatialHash {
|
|||
|
||||
export default class UpdateSpatialHash extends System {
|
||||
|
||||
static get priority() {
|
||||
return {
|
||||
after: 'CalculateAabbs',
|
||||
};
|
||||
}
|
||||
|
||||
deindex(entities) {
|
||||
super.deindex(entities);
|
||||
for (const id of entities) {
|
||||
|
|
|
@ -134,10 +134,10 @@ test('ticks systems', () => {
|
|||
}
|
||||
|
||||
tick(elapsed) {
|
||||
for (const [position, momentum] of this.select('default')) {
|
||||
position.x += momentum.x * elapsed;
|
||||
position.y += momentum.y * elapsed;
|
||||
position.z += momentum.z * elapsed;
|
||||
for (const {Position, Momentum} of this.select('default')) {
|
||||
Position.x += Momentum.x * elapsed;
|
||||
Position.y += Momentum.y * elapsed;
|
||||
Position.z += Momentum.z * elapsed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,19 @@
|
|||
export default class Query {
|
||||
|
||||
$$criteria = {with: [], without: []};
|
||||
|
||||
$$ecs;
|
||||
$$index = new Set();
|
||||
|
||||
constructor(parameters, Components) {
|
||||
constructor(parameters, ecs) {
|
||||
this.$$ecs = ecs;
|
||||
for (let i = 0; i < parameters.length; ++i) {
|
||||
const parameter = parameters[i];
|
||||
switch (parameter.charCodeAt(0)) {
|
||||
case '!'.charCodeAt(0):
|
||||
this.$$criteria.without.push(Components[parameter.slice(1)]);
|
||||
this.$$criteria.without.push(ecs.Components[parameter.slice(1)]);
|
||||
break;
|
||||
default:
|
||||
this.$$criteria.with.push(Components[parameter]);
|
||||
this.$$criteria.with.push(ecs.Components[parameter]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +63,6 @@ export default class Query {
|
|||
|
||||
select() {
|
||||
const it = this.$$index.values();
|
||||
const value = [];
|
||||
return {
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
|
@ -72,11 +72,7 @@ export default class Query {
|
|||
if (result.done) {
|
||||
return {done: true, value: undefined};
|
||||
}
|
||||
for (let i = 0; i < this.$$criteria.with.length; ++i) {
|
||||
value[i] = this.$$criteria.with[i].get(result.value);
|
||||
}
|
||||
value[this.$$criteria.with.length] = result.value;
|
||||
return {done: false, value};
|
||||
return {done: false, value: this.$$ecs.get(result.value)};
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,15 +23,24 @@ Components.A.createMany([[2], [3]]);
|
|||
Components.B.createMany([[1], [2]]);
|
||||
Components.C.createMany([[2], [4]]);
|
||||
|
||||
const fakeEcs = (Components) => ({
|
||||
Components,
|
||||
get(id) {
|
||||
return Object.fromEntries(
|
||||
Object.entries(Components)
|
||||
.map(([componentName, Component]) => [componentName, Component.get(id)])
|
||||
.concat([['id', id]])
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
function testQuery(parameters, expected) {
|
||||
const query = new Query(parameters, Components);
|
||||
const query = new Query(parameters, fakeEcs(Components));
|
||||
query.reindex([1, 2, 3]);
|
||||
expect(query.count)
|
||||
.to.equal(expected.length);
|
||||
for (const _ of query.select()) {
|
||||
expect(_.length)
|
||||
.to.equal(parameters.filter((spec) => '!'.charCodeAt(0) !== spec.charCodeAt(0)).length + 1);
|
||||
expect(expected.includes(_.pop()))
|
||||
expect(expected.includes(_.id))
|
||||
.to.equal(true);
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +60,7 @@ test('can query excluding', () => {
|
|||
});
|
||||
|
||||
test('can deindex', () => {
|
||||
const query = new Query(['A'], Components);
|
||||
const query = new Query(['A'], fakeEcs(Components));
|
||||
query.reindex([1, 2, 3]);
|
||||
expect(query.count)
|
||||
.to.equal(2);
|
||||
|
@ -63,7 +72,7 @@ test('can deindex', () => {
|
|||
test('can reindex', () => {
|
||||
const Test = new (wrapSpecification('Test', {a: {type: 'int32', defaultValue: 420}}));
|
||||
Test.createMany([[2], [3]]);
|
||||
const query = new Query(['Test'], {Test});
|
||||
const query = new Query(['Test'], fakeEcs({Test}));
|
||||
query.reindex([2, 3]);
|
||||
expect(query.count)
|
||||
.to.equal(2);
|
||||
|
@ -74,10 +83,10 @@ test('can reindex', () => {
|
|||
});
|
||||
|
||||
test('can select', () => {
|
||||
const query = new Query(['A'], Components);
|
||||
const query = new Query(['A'], fakeEcs(Components));
|
||||
query.reindex([1, 2, 3]);
|
||||
const it = query.select();
|
||||
const result = it.next();
|
||||
expect(result.value[0].a)
|
||||
const {value: {A}} = it.next();
|
||||
expect(A.a)
|
||||
.to.equal(420);
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ export default class System {
|
|||
this.ecs = ecs;
|
||||
const queries = this.constructor.queries();
|
||||
for (const i in queries) {
|
||||
this.queries[i] = new Query(queries[i], ecs.Components);
|
||||
this.queries[i] = new Query(queries[i], ecs);
|
||||
}
|
||||
this.reindex(ecs.entities);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user