simulation: derive the stepper latch from moving bodies on add/remove
One helper sets stepper.blocked from _moving_bodies() after add_body, pre-init remove_body, initialize and stepper recreation, so the latch never disagrees with motion ownership. Tests: latch follows add/remove; the after-close assertion checks the actual refusal. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b448bc3f71
commit
e682d16c3a
@@ -232,6 +232,16 @@ def test_add_body_and_set_body_route_targets(monkeypatch):
|
||||
**kwargs)
|
||||
|
||||
|
||||
def test_stepper_latch_follows_moving_bodies(monkeypatch):
|
||||
sim = routed_simulation(monkeypatch)
|
||||
still = sim.add_body("circle", (100., 40.), 5.)
|
||||
assert sim.stepper.blocked is None
|
||||
moving = sim.add_body("circle", (50., 40.), 10., translation=Translation((0., 0., -1., 1.), .1))
|
||||
assert sim.stepper.blocked is not None
|
||||
sim.remove_body(moving) # removing the last translating circle clears the latch
|
||||
assert sim.stepper.blocked is None and sim.bodies.get(still).motion is None
|
||||
|
||||
|
||||
def validate(monkeypatch, objects, flags=None, **cfg):
|
||||
sim = routed_simulation(monkeypatch)
|
||||
for obj in objects:
|
||||
@@ -306,5 +316,5 @@ def test_failed_moving_step_marks_simulation_failed(monkeypatch):
|
||||
with pytest.raises(RuntimeError, match="unknown"): # no retry on the failed circle
|
||||
motion.advance(lambda *_: None, lambda: None, lambda: None)
|
||||
sim.close() # close still works
|
||||
with pytest.raises(Exception): # no re-entry after close
|
||||
with pytest.raises(RuntimeError, match="Simulation failed"): # no re-entry after close
|
||||
sim.run(1)
|
||||
|
||||
Reference in New Issue
Block a user