90 lines
1.8 KiB
JavaScript
90 lines
1.8 KiB
JavaScript
import Digraph from '@/util/digraph.js';
|
|
|
|
import Query from './query.js';
|
|
|
|
export default class System {
|
|
|
|
active = false;
|
|
|
|
ecs;
|
|
|
|
elapsed = 0;
|
|
|
|
frequency;
|
|
|
|
queries = {};
|
|
|
|
constructor(ecs) {
|
|
this.ecs = ecs;
|
|
const queries = this.constructor.queries();
|
|
for (const i in queries) {
|
|
this.queries[i] = new Query(queries[i], ecs);
|
|
}
|
|
}
|
|
|
|
deindex(entityIds) {
|
|
for (const i in this.queries) {
|
|
this.queries[i].deindex(entityIds);
|
|
}
|
|
}
|
|
|
|
static get priority() {
|
|
return {
|
|
phase: 'normal',
|
|
}
|
|
}
|
|
|
|
static queries() {
|
|
return {};
|
|
}
|
|
|
|
reindex(entityIds) {
|
|
for (const i in this.queries) {
|
|
this.queries[i].reindex(entityIds);
|
|
}
|
|
}
|
|
|
|
schedule() {
|
|
this.elapsed = this.frequency;
|
|
}
|
|
|
|
select(query) {
|
|
return this.queries[query].select();
|
|
}
|
|
|
|
static sort(Systems) {
|
|
const phases = {
|
|
'pre': new Digraph(),
|
|
'normal': new Digraph(),
|
|
'post': new Digraph(),
|
|
};
|
|
for (const systemName in Systems) {
|
|
const {priority} = Systems[systemName];
|
|
const phase = phases[priority.phase || 'normal'];
|
|
phase.ensureTail(systemName);
|
|
if (priority.before) {
|
|
for (const before of Array.isArray(priority.before) ? priority.before : [priority.before]) {
|
|
phase.addDependency(before, systemName);
|
|
}
|
|
}
|
|
if (priority.after) {
|
|
for (const after of Array.isArray(priority.after) ? priority.after : [priority.after]) {
|
|
phase.addDependency(systemName, after);
|
|
}
|
|
}
|
|
}
|
|
const sorted = [
|
|
...phases['pre'].sort(),
|
|
...phases['normal'].sort(),
|
|
...phases['post'].sort(),
|
|
];
|
|
return Object.fromEntries(
|
|
Object.entries(Systems)
|
|
.toSorted(([l], [r]) => sorted.indexOf(l) - sorted.indexOf(r)),
|
|
);
|
|
}
|
|
|
|
tick() {}
|
|
|
|
}
|