Closed dwhall closed 3 years ago
The problem is how to do this:
module1.py:
foo = FooAhsm()
module2.py:
bar = BarAhsm()
foo.post_fifo(farc.Event(farc.Signal.BAZ, 'value'))
and there is likely a way to do this (because Python is awesome). But just because we have the power to do something doesn't mean we should do it.
If you have the problem mentioned above, I propose this two-step solution. Step 1, solve your python module dependencies completely ignoring farc and state machines. That is, make it so that wherever you are wanting to call foo.post_fifo(), that you could call foo.any_method().
Step 2, Encapsulate your state machines' Events with a public method in your state machine's class. So, instead of foo.post_fifo(farc.Event(farc.Signal.BAZ, 'value'))
in the example above, you should make the following new method in class FooAhsm
:
def post_baz(self, value):
self.post_fifo(farc.Event(farc.Signal.BAZ, value))
This encapsulation is nice because it means if you have a complex value (like a tuple with many fields), you only need to know those details in one module, not the event-poster and event-handler modules. This encapsulation also lets the Python compiler make sure the poster and handler modules have matching signatures.
See post_rx_action() here, for a real-world example.
The implementation of Ahsm.postFIFO() requires the sender to have a reference to the instance of the recipient. If the sender and the recipient are in separate modules, how do they get the reference to the instance? The current workaround is that the sender and receiver must use the pub/sub pattern via Framework.publish().