Closed ghost closed 3 years ago
flecs: https://github.com/SanderMertens/flecs/blob/master/docs/Manual.md
To my untrained eyes, this sounds like what the change detection system accomplishes. Could you elaborate what you would like to achieve with this that the current change detection system does not solve?
To my untrained eyes, this sounds like what the change detection system accomplishes. Could you elaborate what you would like to achieve with this that the current change detection system does not solve?
Thanks for reply me.
Now, I explain by a example, such as the following code, I modify 3 entities in 10003 entities, and Query<, Changed
And the scene is many object, but I changed a little obejct per frame
Just for clarity, the example above does actually run without failing the assert. Count is 3 at the end of execution. This isn't a bug. @moyy is pointing out that Changed is a per-entity filter that is evaluated during iteration. So if there are 10,000 entities with the i32
component, we are checking 10,000 i32
component change states during iteration (this is hidden from the user ... the iterator only returns changed entities).
This was an intentional tradeoff I made to make "automatic change tracking" a performant thing to do globally by default. Any method that involves pushing changes to a dense list (without a full entity scan) would have a significant performance impact when derefing Mut pointers (ex: check to see if we've already pushed a change (to avoid dupes), grab unique access to a shared list (either a RefCell if Mut doesn't need to be Send/Sync, or a Mutex or crossbeam channel for Send/Sync), then push the changed Entity (and potentially allocate)). And then after that, we would need to consolidate changes across queries, which would also involve more allocations and would require de-duplication (so either a sort or a hashmap, neither of which is cheap).
@BoxyUwU had the idea of making "changed status" a part of archetypes, but that would likely also be prohibitively expensive to do by default.
I briefly looked into the Entitas implementation:
We've been discussing adding "reactive ECS" elements to Bevy ECS, but we can't adopt the Entitas implementation without throwing away the things that make Bevy ECS special (parallel, lockless, resource access-aware system execution).
We could consider building Entitas-style reactions in "exclusive single-threaded" systems (probably with a new set of high level reactive apis). But I'd like to explore ways to integrate reactions into the existing parallel context first.
It looks like Unity's ECS (which is parallel) uses an approach very similar to Bevy's. Getting changed components requires checking each component's version against the system's version: https://www.effectiveunity.com/ecs/07-how-to-build-reactive-systems-with-unity-ecs-part-2/
Low performance like move a little obejcts in many static object scene
Let's Think such scene like GUI, a millision of static item, but per frame only low some is moving, now is listener by update stage's system running per frame, event if add query filter Changed.
Add the ReactiveSystem like Entita, more see Entita
reference by the aticle:
"Let’s base it on an example. Imagine we have a tower defence game and we need to implement find target system. In a naive implementation, we could just go other all enemies and figure out if an enemy is close enough. However we could have a small optimisation, we could introduce a Moved component, which indicates that an enemy just moved, so in the find target system, we could iterate only through the enemies which just moved. This optimisation reduces the set of enemies we have to iterate through. Having tag components like Moved can be tricky in regard to it’s life cycle. Moved component has to be added in every system which changes/adds Position. So we might end-up with code duplication. Moved component might be consumed by multiple systems, this means that the removal of the tag component becomes non trivial as well. All this hassle can be simplified, when we introduce a concept of reactive system. A reactive system is executed only on entities which got certain component added/removed or replaced. In our small example, the target system is a reactive system, which works only on entities, which moved since last time this system was executed. The semantics of the system stay the same, but reactive system makes the Moved tag component redundant and remove the cognitive load of managing this tag components life cycle. Introducing the concept of reactive system, profoundly changed the way, we implemented UI and game play systems."