rj00a / evenio

An event-driven Entity Component System
MIT License
139 stars 14 forks source link

Plugin order will transfer to system order #19

Closed MiniaczQ closed 8 months ago

MiniaczQ commented 9 months ago

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 secondary B, 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 prevent A_system from running by deleting the event in B_system.

While I'm not sure how common this or similar scenarios are, they seem like something worth addressing.

Solutions

rj00a commented 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.

MiniaczQ commented 8 months ago

Flecs Docs

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. :)

rj00a commented 8 months ago

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