silphius/app/ecs/query.js

85 lines
1.9 KiB
JavaScript
Raw Normal View History

2024-06-10 22:42:30 -05:00
export default class Query {
$$criteria = {with: [], without: []};
$$index = new Set();
constructor(parameters, Types) {
for (let i = 0; i < parameters.length; ++i) {
const parameter = parameters[i];
switch (parameter.charCodeAt(0)) {
case '!'.charCodeAt(0):
this.$$criteria.without.push(Types[parameter.slice(1)]);
break;
default:
this.$$criteria.with.push(Types[parameter]);
break;
}
}
}
get count() {
return this.$$index.size;
}
deindex(ids) {
for (let i = 0; i < ids.length; ++i) {
this.$$index.delete(ids[i]);
}
}
reindex(ids) {
if (0 === this.$$criteria.with.length && 0 === this.$$criteria.without.length) {
for (const id of ids) {
this.$$index.add(id);
}
return;
}
for (const id of ids) {
let should = true;
for (let j = 0; j < this.$$criteria.with.length; ++j) {
if ('undefined' === typeof this.$$criteria.with[j].get(id)) {
should = false;
break;
}
}
if (should) {
for (let j = 0; j < this.$$criteria.without.length; ++j) {
if ('undefined' !== typeof this.$$criteria.without[j].get(id)) {
should = false;
break;
}
}
}
if (should) {
this.$$index.add(id);
}
else if (!should) {
this.$$index.delete(id);
}
}
}
select() {
const it = this.$$index.values();
const value = [];
return {
[Symbol.iterator]() {
return this;
},
next: () => {
const result = it.next();
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};
},
};
}
}