Follow-up from #26 (cycle detection for scene_parent/attach_to()/scene_children=).
The cycle check added there walks the new parent's full ancestor chain on every single reparenting call, done eagerly and uncached:
ancestor = parent
while ancestor is not None:
if ancestor is self:
raise ValueError(...)
ancestor = ancestor.scene_parent
Deliberately kept simple -- O(depth) per call, no caching -- since the scene graphs this package deals with in practice are small (robot links, a handful of attached objects), so this is nowhere near a bottleneck today. Not a live bug, just flagging the tradeoff for later: if a use case ever comes up with much deeper graphs or very frequent reparenting (e.g. inside a hot per-step loop), this would be worth revisiting -- e.g. a cached depth/generation counter per node, invalidated only on structural change, to avoid re-walking the same chain repeatedly.
No action needed unless that situation actually arises.
Follow-up from #26 (cycle detection for
scene_parent/attach_to()/scene_children=).The cycle check added there walks the new parent's full ancestor chain on every single reparenting call, done eagerly and uncached:
Deliberately kept simple --
O(depth)per call, no caching -- since the scene graphs this package deals with in practice are small (robot links, a handful of attached objects), so this is nowhere near a bottleneck today. Not a live bug, just flagging the tradeoff for later: if a use case ever comes up with much deeper graphs or very frequent reparenting (e.g. inside a hot per-step loop), this would be worth revisiting -- e.g. a cached depth/generation counter per node, invalidated only on structural change, to avoid re-walking the same chain repeatedly.No action needed unless that situation actually arises.