Boost logo

Boost Users :

Subject: Re: [Boost-users] [statechart] Substates in dll
From: Andreas Huber (ahd6974-spamboostorgtrap_at_[hidden])
Date: 2009-07-13 05:54:33


> 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 list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net