
PreIdle( my_context ctx ) : my_base( ctx ), EntryExitDisplayer( "PreIdle" ) { // Posting is now also possible with stack-allocated events post_event( EvPreIdleStart() ); }
Is this in the latest version of boost::statechart? My compiler seems to
disagree with this statement:
test.cpp:65: error: no matching function for call to
'PreIdle::post_event(EvPreIdleStart)'
/usr/local/include/boost-1_32/boost/statechart/simple_state.hpp:271: note:
candidates are: void boost::statechart::simple_state
sc::result react( const EvPreIdleStart & evt ) { // Instead of mentioning the state machine directly with context< .. >, // the following is often more convenient return outermost_context().react( *this, evt ); }
I agree, but my impression is that the react function could be implemented in any "outer context" which may not be the outmost one, right?
Ok, if you want to have both (i.e. independent development of additional derived state machines *and* independent customization on a per-state basis) the reorganization above won't help you. It pretty much trades one for the other. I.e. now it is no longer possible to develop additional derived FSMs without changing Idle.cpp and Running.cpp. However, I'm confident that even that is possible if you introduce an additional layer of indirection. That is, in your original code instead of:
sc::result MyPump::react( PreRunning & preRunning, const EvPreRunningStart & ) const { return preRunning.transit< MyRunning >(); }
you write something like that:
sc::result MyPump::react( PreRunning & preRunning, const EvPreRunningStart & ) const { return StateFactory::MakeTransition( MyPump, preRunning ); }
I haven't thought much about the implementation of StateFactory, but it seems this should allow you to register arbitrary transitions depending on the current state and the actual derived FSM class, and give you the freedom you want?
Sounds plausible to me, I should spend some free time thinking about how to implement this. But right now I'm running into some problems, maybe it's specific to my platform/compiler/code... but if I'll be grateful if you could provide some help or point me in the right direction. Back to the organization of the PumpBase I posted, I split the code and organize them into the following directory structure ./core/Main.cpp ./core/PumpBase.cpp ./dll/MyPump.cpp ./include/PumpBase.hpp ./include/EntryExitDisplayer.hpp ./include/PumpBaseFactory.hpp I think the file names are pretty self-explanatory. The main program in core directory defines and uses the PumpBase FSM, and I want to implement a DLL (in the dll) directory and define MyPump to customize the PumpBase FSM. The main program would use dlopen/dlsym to load the DLL and get the factory that'll create MyPump. The include directory contains the header files shared by the main program and the dll. Everything compiles file, but when I run the program I get a runtime error from dlopen: Error loading MyPump.so MyPump.so: undefined symbol: _ZTIN5boost10statechart12simple_stateI7PreIdle8PumpBaseNS_3mpl4listIN4mpl_ \ 2naES7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_S7_EELNS0_ \ 12history_modeE0EEE (<-- line is too long to post so I split it up) it looks like some template class inside the boost::statechart code, so I'm not quite sure what the problem is. thanks and thanks for the quick response Dave