Multi-component OnAdd observer fails to trigger for regular entity if singleton term is initialized last
Description
An observer that monitors a combination of a regular component and a singleton component fails to trigger on OnAdd events if the singleton component value is set after the regular entity has been created.
If the singleton is initialized before the regular entity is created, the observer triggers successfully. Order of initialization should not affect declarative observer evaluations.
Note: Tested with Flecs v4.1.6#0 installed via vcpkg.
Steps to Reproduce
Run the following C++ code snippet. The observer inside testObserverWithSingleton is never invoked, even though a valid intersection between EntityComponent and SingletonComponent is fully formed at the end of the scope.
#include <iostream>
#include <flecs.h>
void testObserverWithSingleton() {
struct SingletonComponent { int a {}; };
struct EntityComponent { int b {}; };
flecs::world world;
// 1. Register singleton component type
world.component<SingletonComponent>().add(flecs::Singleton);
// 2. Create observer
world.observer<EntityComponent, SingletonComponent>()
.event(flecs::OnAdd)
.each([](const EntityComponent&, const SingletonComponent&) {
std::cout << "Gotcha!" << std::endl;
});
// 3. Create regular entity first
world.entity().set(EntityComponent { .b = 1 });
// 4. Set singleton value afterwards
world.set(SingletonComponent { .a = 1 });
}
int main() {
testObserverWithSingleton();
return 0;
}Expected Behavior
The console should print "Gotcha!". When world.set(SingletonComponent { ... }) occurs, the observer should evaluate the newly added singleton and trigger for the entity that now satisfies all terms of the observer.
Actual Behavior
Nothing is printed to the console. The observer is completely skipped.
If you swap step 3 and step 4 (so that the singleton is set first, and then the regular entity is created), the observer works perfectly.
Additional Notes
- The exact same issue persists regardless of whether
.yield_existing()is appended to the observer chain or not.
Environment
- Flecs version: v4.1.6#0 (via vcpkg)
- Language Standard: C++20
- Compiler: MSVC (Visual Studio)
- OS: Windows
Source: SanderMertens/flecs