85 lines
2.0 KiB
JavaScript
85 lines
2.0 KiB
JavaScript
export default class Query {
|
|
|
|
$$criteria = {with: [], without: []};
|
|
|
|
$$index = new Set();
|
|
|
|
constructor(parameters, Components) {
|
|
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)]);
|
|
break;
|
|
default:
|
|
this.$$criteria.with.push(Components[parameter]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
get count() {
|
|
return this.$$index.size;
|
|
}
|
|
|
|
deindex(entityIds) {
|
|
for (let i = 0; i < entityIds.length; ++i) {
|
|
this.$$index.delete(entityIds[i]);
|
|
}
|
|
}
|
|
|
|
reindex(entityIds) {
|
|
if (0 === this.$$criteria.with.length && 0 === this.$$criteria.without.length) {
|
|
for (const entityId of entityIds) {
|
|
this.$$index.add(entityId);
|
|
}
|
|
return;
|
|
}
|
|
for (const entityId of entityIds) {
|
|
let should = true;
|
|
for (let j = 0; j < this.$$criteria.with.length; ++j) {
|
|
if ('undefined' === typeof this.$$criteria.with[j].get(entityId)) {
|
|
should = false;
|
|
break;
|
|
}
|
|
}
|
|
if (should) {
|
|
for (let j = 0; j < this.$$criteria.without.length; ++j) {
|
|
if ('undefined' !== typeof this.$$criteria.without[j].get(entityId)) {
|
|
should = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (should) {
|
|
this.$$index.add(entityId);
|
|
}
|
|
else if (!should) {
|
|
this.$$index.delete(entityId);
|
|
}
|
|
}
|
|
}
|
|
|
|
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};
|
|
},
|
|
};
|
|
}
|
|
|
|
}
|