
"Andreas Huber" <ah2003@gmx.net> wrote in message news:c90n7i$gbn$1@sea.gmane.org...
Rob Stewart wrote:
From: Andreas Huber <ah2003@gmx.net>
Could the fsm manage a container of (pointers to) state objects that it populates as it first creates each state object and from which it retrieves a state object when transitioning? IOW, the first time the fsm encounters the need to transition to a given state (from A to B, say), it creates B and tracks it in the container. Upon transition back to A, the fsm locates state A in the container and reuses it.
This is certainly possible. I just have my doubts whether this approach is so much better speed-wise. If you customize state memory management, construction and destruction doesn't take an awful amount of cycles. Searching that state container might well take longer for large FSMs.
That's certainly an important consideration, but I was thinking in terms of something built into the fsm framework, thus providing the benefit for all clients versus requiring clients to do work if they want the speed improvement. If your concern proves correct, then using the container approach isn't helpful. However, the states' base class, which I presume is part of your library, could provide a pool allocator for state objects. That would put the onus on the library, rather than the clients, and would still reduce the (perceived, not proven) overhead caused by creating and destroying state objects on each transition.
<rationale quote> simple_state<> and state<> subclass objects are constructed and destructed only by the state machine. It would therefore be possible to use the state_machine<> allocator instead of forcing the user to overload operator new() and operator delete(). However, a lot of systems employ at most one instance of a particular state machine, which means that a) there is at most one object of a particular state and b) this object is always constructed, accessed and destructed by one and the same thread. We can exploit these facts in a much simpler (and faster) new/delete implementation (for example, see UniqueObject.hpp in the BitMachine example). However, this is only possible as long as we have the freedom to customize memory management for state classes separately. </rationale quote>
Building a pool allocator into state_machine<> or even using the one that the user can pass would mean to needlessly throw away some opportunities for optimization. The user has to make that decision.
Don't forget, though, that part of my proposal was that state objects would have enter() and exit() mfs rather than relying on the ctor and dtor for entry and exit, respectively. That can simplify matters when dealing with exceptions.
The longer I think about it the more am I convinced that separate entry() and exit() functions don't buy you anything w.r.t to exception handling (see my discussion with Dave).
He's definitely the expert on the subject in question. Exception handling aside for a moment, I still would strongly prefer to have separate entry/exit methods in the state object interface; it more clearly relates to the conceptual view of FSMs. And, while we're at it: perhaps the entry()/exit() points should be user configurable (per-state-type) to correspond to the UML notation e.g. "entry() / init()", "exit() / cleanup()" IIRC. As I haven't been following your discussion with Dave; is this also a performance concern (function call overhead)? // Johan