Closed MiniaczQ closed 8 months ago
I agree that the current situation is likely not ideal in the long run. I think we'll need some first-hand experience with the library before deciding on one of these solutions. I'm hoping to gather some of that experience in Valence soon.
However, it's worth pointing out that observers and systems in flecs are run in insertion order, and they have a whole plugin framework in place already. Although there might be some nuance I'm missing since I'm not very familiar with flecs.
From my understanding, this uses the "standard solution/workaround" option, it mentions very clearly how order of plugin (module) imports impacts the system order. The forementioned "standard" is to provide plugins in atomic units, in the example provided that is physics components and physics systems.
This doesn't exactly solve the issue I mentioned, since I addressed strictly system ordering, but since it's battle tested, the issue is clearly not as important as I thought. :)
observers and systems in flecs are run in insertion order
I was wrong about observers. It seems that they run in unspecified/undefined order.
#include <iostream>
#include "flecs.h"
struct Position {
float x, y;
};
struct Velocity {
float x, y;
};
int main() {
flecs::world world;
flecs::observer observer1 = world.observer<Position, Velocity>()
.event(flecs::OnSet)
.each([](const Position &pos, const Velocity &vel) {
std::cout << "1 ";
});
flecs::observer observer2 = world.observer<Position, Velocity>()
.event(flecs::OnSet)
.each([](const Position &pos, const Velocity &vel) {
std::cout << "2 ";
});
flecs::observer observer3 = world.observer<Position, Velocity>()
.event(flecs::OnSet)
.each([](const Position &pos, const Velocity &vel) {
std::cout << "3 ";
});
auto e = world.entity();
e.set<Position>({10, 20});
e.set<Velocity>({1, 2});
e.set<Position>({100, 200});
}
Output:
1 2 3 3 2 1
I jumped the gun a bit, AFAIK there are no plugins in the current implementation, but seeing the similarities to Bevy I expect something similar to pop up.
While small apps can be made very neatly using the 3-variant ordering, introducing plugins may add a lot of problems.
Example
Given a primary plugin
A
and secondaryB
, it's impossible to achieve the following ordering:B_system
->A_system
within a given ordering enum variant. (assuming we can't just switch the plugin order because most systems run A->B) This could be a problem e.g. when trying to preventA_system
from running by deleting the event inB_system
.While I'm not sure how common this or similar scenarios are, they seem like something worth addressing.
Solutions
i8
ori16
should introduce enough granularity for reasonable dependency chains, the enum variants can be reintroduced as standardized constants.