That's interesting. What this does is to move the knowledge that "State1 transitions to State2 in response to EvWhatever" into a separate binary from the one where State1 is implemented. This does seem to address the basic problem. What would happen if we wanted this to scale to more states, so that e.g. there's a State3 that we transition to in response to EvAnother? And so on with more states and events, where we'd like each of State3, State4, etc. to be implemented in their own dll. It would seem that we'd have to build up a hierarchy where we have one inheritance level for each state. This could get cumbersome, but it would probably work.

In any case, for our application, we may not actually require all this. We may be able to accomplish what we need by splitting out the functionality into independent state machines, rather than independent states within a single state machine. We'll need to analyze the kinds of coordination that would have to happen between machines, but at this point I believe we could use this approach.

Thanks very much for your help. I have another (I hope simpler) question, which I'll put in a separate message.

Bill


On Mon, Jul 13, 2009 at 2:54 AM, Andreas Huber <ahd6974-spamboostorgtrap@yahoo.com> wrote:
So taking the TuTest code as an starting point, here's what I would like
to
be able to do:

- Put TuTest.cpp and TuTest.hpp in a dll, TuTest.dll, called by the main
program. Keep the initial transition in the cpp file, as in the test code.
- Make the Initial state react to EvX by transitioning to a new state,
call
it MyState, defined in MyState.dll. MyState, in turn, would have its own
internal transitions and states, which it hides from clients by putting
them
in its own cpp files.

Ok.


In your reply you had said that the state dll, MyState.dll in this case,
won't have a link-time dependency on the state machine; it need only
include
its header. This would be true if the state machine were implemented
entirely in the header. However, the header won't be enough if its initial
transition is hidden in a cpp file; the state would need to link with the
state machine.

Right, my bad. After some reflection, it seems that your assessment is correct. You simply cannot push only some states of a state machine into dlls without introducing a circular dependency between binaries. However, it seems you can circumvent this relatively easily, as follows (UNTESTED):

*** MyStatechartBase.hpp (included from cpps compiled into both dlls) ***

// Depending on your platform, types/functions in this header might need
// to be properly exported/imported

// ...

struct EvWhatever : sc::event< EvWhatever > {};

struct State1;
struct MyStatechartBase : sc::state_machine< MyStatechartBase, State1 >
{
 virtual sc::result react( State1 & state1, const EvWhatever & ev ) = 0;
};

struct State1 : sc::simple_state< State1, MyStatechartBase >
{
 typedef sc::custom_reaction< EvWhatever > reactions;

 sc::result react( const EvWhatever & ev )
 {
  return outermost_context().react( this, ev );
 }
};

*** MyStatechartBase.cpp (compiled into MyStatechartBase.dll) ***

#include "MyStatechartBase.hpp"
// ...

*** MyStatechart.cpp (compiled into MyStatechart.dll) ***

// This might have to be split into hpp/cpp

#include "MyStatechartBase.hpp"
// ...

struct State2 : sc::simple_state< State2, MyStatechartBase > {};

struct MyStatechart : MyStatechartBase
{
 virtual sc::result react( State1 & state1, const EvWhatever & ev )
 {
  return state1.transit< State2 >();
 }
};

Of course, this has two (IMO minor) problems:
1) You cannot hide State1, it must be publicly visible
2) You have to subclass the state machine

It seems this should do pretty much what you want? If not, please let me know.

Regards,


--
Andreas Huber

When replying by private email, please remove the words spam and trap
from the address shown in the header.

_______________________________________________
Boost-users mailing list
Boost-users@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users