def testNestedCallbackContexts(self): last_called = [None] outer_called = "outer called" inner_called = "inner called" def outer(unused_model, unused_data): last_called[0] = outer_called def inner(unused_model, unused_data): last_called[0] = inner_called with core.callback_context("mjcb_passive", outer): # This should execute `outer` a few times. mjlib.mj_step(self.model.ptr, self.data.ptr) self.assertEqual(last_called[0], outer_called) with core.callback_context("mjcb_passive", inner): # This should execute `inner` a few times. mjlib.mj_step(self.model.ptr, self.data.ptr) self.assertEqual(last_called[0], inner_called) # When we exit the inner context, the `mjcb_passive` callback should be # reset to `outer`. mjlib.mj_step(self.model.ptr, self.data.ptr) self.assertEqual(last_called[0], outer_called) # When we exit the outer context, the `mjcb_passive` callback should be # reset to None, and stepping should not affect `last_called`. last_called[0] = None mjlib.mj_step(self.model.ptr, self.data.ptr) self.assertIsNone(last_called[0])
def testSingleCallbackContext(self): callback_was_called = [False] def callback(unused_model, unused_data): callback_was_called[0] = True mjlib.mj_step(self.model.ptr, self.data.ptr) self.assertFalse(callback_was_called[0]) class DummyError(RuntimeError): pass try: with core.callback_context("mjcb_passive", callback): # Stepping invokes the `mjcb_passive` callback. mjlib.mj_step(self.model.ptr, self.data.ptr) self.assertTrue(callback_was_called[0]) # Exceptions should not prevent `mjcb_passive` from being reset. raise DummyError("Simulated exception.") except DummyError: pass # `mjcb_passive` should have been reset to None. callback_was_called[0] = False mjlib.mj_step(self.model.ptr, self.data.ptr) self.assertFalse(callback_was_called[0])