Skip to content

feat: enhance scene graph with entity system improvements#7

Open
mtao wants to merge 2 commits intomainfrom
feature/entity-system
Open

feat: enhance scene graph with entity system improvements#7
mtao wants to merge 2 commits intomainfrom
feature/entity-system

Conversation

@mtao
Copy link
Copy Markdown
Owner

@mtao mtao commented Mar 28, 2026

Summary

Adds four incremental enhancements to the visualization scene graph's Object+AbstractFeature pattern, improving query performance, enabling reactive updates, and providing convenient traversal utilities.

Changes

  1. O(1 feature lookupObject now maintains an unordered_map<type_index, AbstractFeature*> alongside the existing vector<unique_ptr<AbstractFeature>>. find_feature<F>() checks the map first (exact type match), falling back to dynamic_cast scan for base-class queries (only 4 of 55 existing call sites need this).

  2. Feature signals — Adds palacaze/sigslot v1.2.3 as a dependency. New signals:

    • Object::on_feature_added(Object&, AbstractFeature&)
    • Object::on_feature_removing(Object&, AbstractFeature&)
    • Object::on_child_added(Object&, Object&)
    • Object::on_child_removing(Object&, Object&)
    • AbstractFeature::on_modified(AbstractFeature&) with mark_modified() helper
  3. Scene-level FeatureIndex — Subscribes to Object signals and maintains a type_index -> vector<Object*> index. Provides objects_with<F>() (returns span) and count<F>() for O(1) "give me all objects with MeshData" queries. Auto-tracks/untracks children as the scene graph changes.

  4. Traversal API — New methods on Object:

    • for_each_descendant(fn) — DFS pre-order; if fn returns bool, false prunes subtree
    • for_each_ancestor(fn) — walks parent chain; false stops early
    • find_descendant(pred) — returns first matching Object* or nullptr

Testing

  • 25 new test cases added to test_scene_graph.cpp covering all four enhancements
  • All 8 test suites pass: 23,717 total assertions

Design Notes

  • This enhances the existing Object+Feature pattern for the visualization layer (10-100 objects). A separate full ECS (e.g., entt/flecs) would be used in archer for simulation-scale data (10k-1M entities) if needed.
  • sigslot::signal_st is used for zero-overhead single-threaded operation. observer_st base class provides automatic disconnect on destruction.

mtao added 2 commits March 28, 2026 12:10
…ndex, and traversal API

Add four incremental enhancements to the Object+AbstractFeature scene graph:

1. O(1) feature lookup via type_index map in Object (dynamic_cast fallback
   for base-class queries)
2. Feature signals using palacaze/sigslot: on_feature_added/removing,
   on_child_added/removing on Object, and on_modified on AbstractFeature
3. Scene-level FeatureIndex that subscribes to signals and maintains a
   type->objects map for efficient "give me all objects with X" queries
4. Traversal API: for_each_descendant, for_each_ancestor, find_descendant
   with pruning support via bool return values

Adds sigslot v1.2.3 as a wrap-git subproject with custom meson.build.
All 8 test suites pass (23,717 assertions).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant