silphius/app/ecs/system.js

130 lines
2.6 KiB
JavaScript
Raw Normal View History

2024-06-25 10:43:12 -05:00
import Digraph from '@/util/digraph.js';
2024-06-10 22:42:30 -05:00
import Query from './query.js';
export default class System {
2024-06-14 15:18:55 -05:00
active = false;
2024-06-10 22:42:30 -05:00
destroying = [];
ecs;
2024-06-30 15:54:23 -05:00
elapsed = 0;
frequency;
2024-06-10 22:42:30 -05:00
queries = {};
constructor(ecs) {
this.ecs = ecs;
const queries = this.constructor.queries();
for (const i in queries) {
2024-06-26 07:41:07 -05:00
this.queries[i] = new Query(queries[i], ecs);
2024-06-10 22:42:30 -05:00
}
2024-06-14 15:18:55 -05:00
this.reindex(ecs.entities);
}
createEntity(components) {
return this.ecs.create(components);
}
createManyEntities(componentsList) {
return this.ecs.createMany(componentsList);
2024-06-10 22:42:30 -05:00
}
2024-06-11 19:10:57 -05:00
deindex(entityIds) {
2024-06-10 22:42:30 -05:00
for (const i in this.queries) {
2024-06-11 19:10:57 -05:00
this.queries[i].deindex(entityIds);
2024-06-10 22:42:30 -05:00
}
}
2024-06-11 19:10:57 -05:00
destroyEntity(entityId) {
this.destroyManyEntities([entityId]);
2024-06-10 22:42:30 -05:00
}
2024-06-11 19:10:57 -05:00
destroyManyEntities(entityIds) {
for (let i = 0; i < entityIds.length; i++) {
this.destroying.push(entityIds[i]);
2024-06-10 22:42:30 -05:00
}
}
2024-06-27 10:17:47 -05:00
async insertComponents(entityId, components) {
return this.ecs.insert(entityId, components);
2024-06-14 15:18:55 -05:00
}
2024-06-27 10:17:47 -05:00
async insertManyComponents(components) {
return this.ecs.insertMany(components);
2024-06-10 22:42:30 -05:00
}
2024-06-25 10:43:12 -05:00
static get priority() {
return {
phase: 'normal',
}
}
2024-06-10 22:42:30 -05:00
static queries() {
return {};
}
2024-06-11 19:10:57 -05:00
reindex(entityIds) {
2024-06-10 22:42:30 -05:00
for (const i in this.queries) {
2024-06-11 19:10:57 -05:00
this.queries[i].reindex(entityIds);
2024-06-10 22:42:30 -05:00
}
}
2024-06-14 15:18:55 -05:00
removeComponents(entityId, components) {
this.ecs.remove(entityId, components);
}
removeManyComponents(entityIds) {
this.ecs.removeMany(entityIds);
}
2024-06-10 22:42:30 -05:00
select(query) {
return this.queries[query].select();
}
2024-06-25 10:43:12 -05:00
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)),
);
}
2024-06-10 22:42:30 -05:00
tickDestruction() {
2024-07-04 09:10:37 -05:00
if (this.destroying.length > 0) {
this.deindex(this.destroying);
}
2024-06-10 22:42:30 -05:00
this.destroying = [];
}
tick() {}
}