[IGSTK-Developers] Repercussions of state machine dispatcher
David Gobbi
dgobbi at atamai.com
Mon Oct 24 03:49:14 EDT 2005
Hi All,
I've been thinking about the state machine dispatcher,
and how it will impact our existing code base.
The idea behind the dispatcher is that all state
machine processing is handled centrally by the
dispatcher. In our existing design, each object
handles its own state machine processing by calling
"ProcessInputs" itself before returning control to
its caller.
Here are two implications of using the dispatcher:
1) Whenever an IGSTK method is called, the requested
processing is not performed until the next time the
dispatcher runs (the dispatcher runs whenever control
returns to the application's main event loop)
2) As a corollary to the above, any IGSTK method that
must do any sort of processing cannot have a return
value. The only way that an IGSTK object can return
information to the method caller is via events.
First I will illustrate why the above items must
be true, and then I will give examples of how this will
impact our code.
Let's say we have an IGSTK object called "Object" with a
RequestAction() method:
void Object::RequestAction(void)
{
m_StateMachine.PushInput(ActionInput);
}
void Object::ActionProcessing(void)
{
... perform some action, then push the next input
}
Now let's say that some code calls object->RequestAction().
When RequestAction() returns, the ActionInput has been pushed,
but the action has not yet been performed.
No action will be performed until the caller returns, and
its caller returns (repeat N times), and eventually we get
back to the application's main event loop. At that time,
the dispatcher will be invoked, and it will process the
queued inputs. Then, finally, our "ActionProcessing()"
is called!
Also, Since the action is not performed before RequestAction()
returns, it is impossible for RequestAction() to produce
a meaningful return value. Information can only be returned
to the calling object via events.
The above was already stated in our Weds meeting, but it
is worth reiterating. This is just like traditional
event-driven programming, but taken to the extreme: every
method call is translated into an event!
To be clear on my feeling here, I think this is absolutely
nuts.
Take, for example, the code in PolarisTracker that detects
and activates the tools that are plugged into the Polaris
(in the code, the method is PolarisTracker::EnableToolPorts())
This sends a sequence of 8 commands to the Polaris, and is
currently done within one state transition of igstkTracker.
With the state machine dispatcher in place, I can't write
one PolarisTracker method that sends all 8 commands via
the SerialCommunication object.
Instead, I need to write two PolarisTracker methods for
each of the eight commands: one to send the command to
the Polaris, and another to receive the reply via an
event. Plus, I need to add eight states: one state
in which to wait for each reply.
And then I need to repeat this process for each of the
other PolarisTracker interface methods...
Make it stop! I like the state machine the way it is!
State machine reentrancy is only a problem if we pass
events around in cycles. And if we're worried about
that, then we can solve that problem by having an
event queue instead of a state machine dispatcher.
- David
More information about the IGSTK-Developers
mailing list