#ifndef __MACHO_HPP__
#define __MACHO_HPP__
#include <new>
#include <cassert>
class TestAccess;
#define TOPSTATE(TOP) \
struct TOP : public ::Macho::Link< TOP, ::Macho::TopBase< TOP > >
#define SUBSTATE(STATE, SUPERSTATE) \
struct STATE : public ::Macho::Link< STATE, SUPERSTATE >
#define TSUBSTATE(STATE, SUPERSTATE) \
struct STATE : public ::Macho::Link< STATE<typename SUPERSTATE::ANCHOR>, typename SUPERSTATE::SELF >
#define STATE(S) \
public: \
typedef S SELF; \
typedef S ANCHOR; \
\
\
S(::Macho::_StateInstance & instance) : LINK(instance) {} \
~S() {} \
static const char * _state_name() { return #S; } \
\
Box & box() { return *static_cast<Box *>(_box()); } \
friend class ::_VS8_Bug_101615;
#define TSTATE(S) \
typedef S SELF; \
typedef typename S::SUPER SUPER; \
typedef typename S::TOP TOP; \
typedef typename S::ANCHOR ANCHOR; \
typedef ::Macho::Link<S, SUPER> LINK; \
S(::Macho::_StateInstance & instance) : LINK(instance) {} \
~S() {} \
static const char * _state_name() { return #S; } \
typename S::Box & box() { return *static_cast<typename S::Box *>(this->_box()); } \
friend class ::_VS8_Bug_101615; \
using LINK::dispatch; \
using LINK::machine; \
\
template<class U> void setState() { LINK::template setState<U>(); } \
template<class U, class P1> void setState(const P1 & p1) { LINK::template setState<U, P1>(p1); } \
template<class U, class P1, class P2> void setState(const P1 & p1, const P2 & p2) { LINK::template setState<U, P1, P2>(p1, p2); } \
template<class U, class P1, class P2, class P3> void setState(const P1 & p1, const P2 & p2, const P3 & p3) { LINK::template setState<U, P1, P2>(p1, p2, p3); } \
template<class U, class P1, class P2, class P3, class P4> void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) { LINK::template setState<U, P1, P2>(p1, p2, p3, p4); } \
template<class U, class P1, class P2, class P3, class P4, class P5> void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) { LINK::template setState<U, P1, P2>(p1, p2, p3, p4, p5); } \
template<class U, class P1, class P2, class P3, class P4, class P5, class P6> void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) { LINK::template setState<U, P1, P2>(p1, p2, p3, p4, p5, p6); } \
template<class U> void setStateHistory() { LINK::template setStateHistory<U>(); } \
void setState(const class Alias & state) { LINK::setState(state); }
#define DEEPHISTORY() \
private: \
\
virtual void _saveHistory(::Macho::_StateInstance & self, ::Macho::_StateInstance & shallow, ::Macho::_StateInstance & deep) \
{ self.setHistory(&deep); SELF::SUPER::_setHistorySuper(self, deep); } \
protected: \
\
virtual void _setHistorySuper(::Macho::_StateInstance & self, ::Macho::_StateInstance & deep) \
{ self.setHistorySuper(deep); } \
public:
#define HISTORY() \
private: \
\
virtual void _saveHistory(::Macho::_StateInstance & self, ::Macho::_StateInstance & shallow, ::Macho::_StateInstance & deep) \
{ self.setHistory(&shallow); SELF::SUPER::_setHistorySuper(self, deep); } \
protected: \
\
virtual void _setHistorySuper(::Macho::_StateInstance & self, ::Macho::_StateInstance & deep) \
{ self.setHistorySuper(deep); } \
public:
#define PERSISTENT() \
private: \
virtual void _deleteBox(::Macho::_StateInstance & instance) {} \
public:
namespace Macho {
class _MachineBase;
template<class T>
class Machine;
template<class T>
class IEvent;
class _StateInstance;
typedef unsigned int ID;
typedef void * Key;
template<class T, class U>
struct _SameType {
};
template<class T>
struct _SameType<T, T> {
typedef bool Check;
};
template<class R>
struct DR {
typedef R T;
};
template<class R>
struct DR<R &> {
typedef R T;
};
template<class R>
struct DR<const R &> {
typedef R T;
};
template<class T, int I>
struct Anchor : public T {
typedef Anchor<T, I> SELF;
typedef SELF ANCHOR;
enum { NUMBER = I };
protected:
Anchor(_StateInstance & instance) : T(instance) {}
};
class _EmptyBox {
_EmptyBox() {}
public:
static _EmptyBox theEmptyBox;
};
template<class B>
void * _createBox(void * & place) {
if (!place)
place = ::operator new(sizeof(B));
new (place) B;
void * box = place;
place = 0;
return box;
}
template<class B>
void _deleteBox(void * & box, void * & place) {
assert(box);
assert(!place);
static_cast<B *>(box)->~B();
place = box;
box = 0;
}
#ifdef MACHO_SNAPSHOTS
template<class B>
void * _cloneBox(void * other) {
assert(other);
return new B(*static_cast<B *>(other));
}
#endif
template<>
void * _createBox<_EmptyBox>(void * & place);
template<>
void _deleteBox<_EmptyBox>(void * & box, void * & place);
#ifdef MACHO_SNAPSHOTS
template<>
void * _cloneBox<_EmptyBox>(void * other);
#endif
struct _KeyData {
typedef _StateInstance & (*Generator)(_MachineBase & machine);
typedef bool (*Predicate)(Key);
typedef const char * (*NameFn)();
const Generator instanceGenerator;
const Predicate childPredicate;
const NameFn name;
const ID id;
};
class _StateSpecification {
public:
virtual ~_StateSpecification() {}
static bool isChild(Key key) {
return false;
}
protected:
_StateSpecification(_StateInstance & instance)
: _myStateInstance(instance)
{}
template<class S>
void setState();
template<class S, class P1>
void setState(const P1 & p1);
template<class S, class P1, class P2>
void setState(const P1 & p1, const P2 & p2);
template<class S, class P1, class P2, class P3>
void setState(const P1 & p1, const P2 & p2, const P3 & p3);
template<class S, class P1, class P2, class P3, class P4>
void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4);
template<class S, class P1, class P2, class P3, class P4, class P5>
void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5);
template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
void setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6);
template<class S>
void setStateHistory();
void setState(const class Alias & state);
template<class S>
void setStateBox(typename S::Box * box = 0);
template<class S>
void setStateDirect(typename S::Box * box = 0);
virtual void _restore(_StateInstance & current);
void setState(_StateInstance & current);
virtual void _shutdown();
virtual void _setHistorySuper(_StateInstance & self, _StateInstance & deep) {}
private:
virtual void exit() {}
virtual void entry() {}
virtual void init() {}
private:
template<class T>
friend class TopBase;
template<class C, class P>
friend class Link;
friend class _StateInstance;
friend class _RootInstance;
friend class _MachineBase;
static _StateInstance & _getInstance(_MachineBase & machine);
virtual void _deleteBox(_StateInstance & instance) {}
virtual void _saveHistory(_StateInstance & self, _StateInstance & shallow, _StateInstance & deep) {}
private:
_StateInstance & _myStateInstance;
};
template<class T>
class TopBase : public _StateSpecification {
public:
typedef T TOP;
protected:
TopBase(_StateInstance & instance)
: _StateSpecification(instance)
{}
void dispatch(IEvent<TOP> * event);
_MachineBase & machine();
};
template<class C, class P>
class Link : public P {
public:
typedef P SUPER;
typedef typename P::TOP TOP;
typedef _EmptyBox Box;
static Key key();
static Alias alias();
static bool isChild(Key other) {
return key() == other || SUPER::isChild(other);
}
static bool isParent(Key other) {
return static_cast<_KeyData *>(other)->childPredicate(key());
}
static bool isCurrent(const _MachineBase & m);
static bool isCurrentDirect(const _MachineBase & m);
static void clearHistory(_MachineBase & m);
static void clearHistoryDeep(_MachineBase & m);
static Alias history(const _MachineBase & m);
protected:
typedef Link<C, P> LINK;
Link(_StateInstance & instance);
virtual void entry() {}
virtual void init() {}
virtual void exit() {}
void * _box();
private:
template<class U, class V>
friend class Link;
friend class _StateSpecification;
friend class Machine<TOP>;
friend class Alias;
friend class ::TestAccess;
static _StateInstance & _getInstance(_MachineBase & machine);
virtual void _deleteBox(_StateInstance & instance);
virtual void _saveHistory(_StateInstance & self, _StateInstance & shallow, _StateInstance & deep) {
this->_setHistorySuper(self, deep);
}
private:
_StateInstance & _myStateInstance;
};
template<class S>
class StateID {
public:
static const ID value;
};
class _StateInstance {
protected:
_StateInstance(_MachineBase & machine, _StateInstance * parent);
public:
virtual ~_StateInstance();
void entry(_StateInstance & previous, bool first = true);
void exit(_StateInstance & next);
void init(bool history);
void saveHistory(_StateInstance & shallow, _StateInstance & deep) {
mySpecification->_saveHistory(*this, shallow, deep);
}
void setHistorySuper(_StateInstance & deep) {
if (myParent)
myParent->saveHistory(*this, deep);
}
#ifdef MACHO_SNAPSHOTS
void copy(_StateInstance & original);
_StateInstance * clone(_MachineBase & newMachine);
#endif
void shutdown() {
mySpecification->_shutdown();
}
void restore(_StateInstance & instance) {
mySpecification->_restore(instance);
}
virtual ID id() = 0;
virtual Key key() = 0;
virtual const char * name() = 0;
virtual _StateInstance * create(_MachineBase & machine, _StateInstance * parent) = 0;
virtual void createBox() = 0;
virtual void deleteBox() = 0;
#ifdef MACHO_SNAPSHOTS
virtual void cloneBox(void * box) = 0;
#endif
void setBox(void * box) {
assert(!myBox);
if (myBoxPlace) {
::operator delete(myBoxPlace);
myBoxPlace = 0;
}
myBox = box;
}
bool isChild(const _StateInstance & instance) {
return this == &instance || (myParent && myParent->isChild(instance));
}
_StateSpecification & specification() {
assert(mySpecification);
return *mySpecification;
}
void * box() {
assert(myBox);
return myBox;
}
_MachineBase & machine() {
return myMachine;
}
void setHistory(_StateInstance * history) const {
myHistory = history;
}
_StateInstance * history() const {
return myHistory;
}
protected:
_MachineBase & myMachine;
_StateSpecification * mySpecification; mutable _StateInstance * myHistory;
_StateInstance * myParent;
void * myBox;
void * myBoxPlace; };
class _RootInstance : public _StateInstance {
protected:
friend class _StateSpecification;
_RootInstance(_MachineBase & machine, _StateInstance * parent)
: _StateInstance(machine, parent)
{
mySpecification = new _StateSpecification(*this);
}
public:
virtual ID id() {
return 0;
}
virtual Key key() {
assert(false); return 0;
}
virtual void createBox() {}
virtual void deleteBox() {}
#ifdef MACHO_SNAPSHOTS
virtual void cloneBox(void * box) {}
#endif
virtual const char * name() { return "Root"; }
virtual _StateInstance * create(_MachineBase & machine, _StateInstance * parent) {
return new _RootInstance(machine, parent);
}
};
template<class S>
class _SubstateInstance : public _StateInstance {
protected:
template<class C, class P>
friend class Link;
_SubstateInstance(_MachineBase & machine, _StateInstance * parent)
: _StateInstance(machine, parent)
{
assert(parent);
this->mySpecification = new S(*this);
}
public:
typedef typename S::Box Box;
virtual ~_SubstateInstance() {
if (this->myBox)
Macho::_deleteBox<Box>(myBox, myBoxPlace);
}
virtual const char * name() { return S::_state_name(); }
virtual ID id() {
return StateID<S>::value;
}
virtual Key key() {
return S::key();
}
virtual _StateInstance * create(_MachineBase & machine, _StateInstance * parent) {
return new _SubstateInstance<S>(machine, parent);
}
virtual void createBox() {
if (!this->myBox)
this->myBox = Macho::_createBox<Box>(myBoxPlace);
}
virtual void deleteBox() {
assert(myBox);
Macho::_deleteBox<Box>(myBox, myBoxPlace);
}
#ifdef MACHO_SNAPSHOTS
virtual void cloneBox(void * box) {
assert(!myBox);
assert(!myBoxPlace);
myBox = Macho::_cloneBox<Box>(box);
}
#endif
};
class _IEventBase {
public:
virtual ~_IEventBase() {}
virtual void dispatch(_StateInstance &) = 0;
};
template<class TOP>
class IEvent : protected _IEventBase {
friend class Machine<TOP>;
friend class TopBase<TOP>;
};
template<class TOP, class R, class P1, class P2, class P3, class P4, class P5, class P6>
class _Event6 : public IEvent<TOP> {
typedef R (TOP::*Signature)(P1, P2, P3, P4, P5, P6);
public:
_Event6(Signature handler, const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3, const typename DR<P4>::T & p4, const typename DR<P5>::T & p5, const typename DR<P6>::T & p6)
: myHandler(handler)
, myParam1(p1)
, myParam2(p2)
, myParam3(p3)
, myParam4(p4)
, myParam5(p5)
, myParam6(p6)
{}
protected:
void dispatch(_StateInstance & instance) {
TOP & behaviour = static_cast<TOP &>(instance.specification());
(behaviour.*myHandler)(myParam1, myParam2, myParam3, myParam4, myParam5, myParam6);
}
Signature myHandler;
typename DR<P1>::T myParam1;
typename DR<P2>::T myParam2;
typename DR<P3>::T myParam3;
typename DR<P4>::T myParam4;
typename DR<P5>::T myParam5;
typename DR<P6>::T myParam6;
};
template<class TOP, class R, class P1, class P2, class P3, class P4, class P5>
class _Event5 : public IEvent<TOP> {
typedef R (TOP::*Signature)(P1, P2, P3, P4, P5);
public:
_Event5(Signature handler, const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3, const typename DR<P4>::T & p4, const typename DR<P5>::T & p5)
: myHandler(handler)
, myParam1(p1)
, myParam2(p2)
, myParam3(p3)
, myParam4(p4)
, myParam5(p5)
{}
protected:
void dispatch(_StateInstance & instance) {
TOP & behaviour = static_cast<TOP &>(instance.specification());
(behaviour.*myHandler)(myParam1, myParam2, myParam3, myParam4, myParam5);
}
Signature myHandler;
typename DR<P1>::T myParam1;
typename DR<P2>::T myParam2;
typename DR<P3>::T myParam3;
typename DR<P4>::T myParam4;
typename DR<P5>::T myParam5;
};
template<class TOP, class R, class P1, class P2, class P3, class P4>
class _Event4 : public IEvent<TOP> {
typedef R (TOP::*Signature)(P1, P2, P3, P4);
public:
_Event4(Signature handler, const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3, const typename DR<P4>::T & p4)
: myHandler(handler)
, myParam1(p1)
, myParam2(p2)
, myParam3(p3)
, myParam4(p4)
{}
protected:
void dispatch(_StateInstance & instance) {
TOP & behaviour = static_cast<TOP &>(instance.specification());
(behaviour.*myHandler)(myParam1, myParam2, myParam3, myParam4);
}
Signature myHandler;
typename DR<P1>::T myParam1;
typename DR<P2>::T myParam2;
typename DR<P3>::T myParam3;
typename DR<P4>::T myParam4;
};
template<class TOP, class R, class P1, class P2, class P3>
class _Event3 : public IEvent<TOP> {
typedef R (TOP::*Signature)(P1, P2, P3);
public:
_Event3(Signature handler, const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3)
: myHandler(handler)
, myParam1(p1)
, myParam2(p2)
, myParam3(p3)
{}
protected:
void dispatch(_StateInstance & instance) {
TOP & behaviour = static_cast<TOP &>(instance.specification());
(behaviour.*myHandler)(myParam1, myParam2, myParam3);
}
Signature myHandler;
typename DR<P1>::T myParam1;
typename DR<P2>::T myParam2;
typename DR<P3>::T myParam3;
};
template<class TOP, class R, class P1, class P2>
class _Event2 : public IEvent<TOP> {
typedef R (TOP::*Signature)(P1, P2);
public:
_Event2(Signature handler, const typename DR<P1>::T & p1, const typename DR<P2>::T & p2)
: myHandler(handler)
, myParam1(p1)
, myParam2(p2)
{}
protected:
void dispatch(_StateInstance & instance) {
TOP & behaviour = static_cast<TOP &>(instance.specification());
(behaviour.*myHandler)(myParam1, myParam2);
}
Signature myHandler;
typename DR<P1>::T myParam1;
typename DR<P2>::T myParam2;
};
template<class TOP, class R, class P1>
class _Event1 : public IEvent<TOP> {
typedef R (TOP::*Signature)(P1);
public:
_Event1(Signature handler, const typename DR<P1>::T & p1)
: myHandler(handler)
, myParam1(p1)
{}
protected:
void dispatch(_StateInstance & instance) {
TOP & behaviour = static_cast<TOP &>(instance.specification());
(behaviour.*myHandler)(myParam1);
}
Signature myHandler;
typename DR<P1>::T myParam1;
};
template<class TOP, class R>
class _Event0 : public IEvent<TOP> {
typedef R (TOP::*Signature)();
public:
_Event0(Signature handler)
: myHandler(handler)
{}
protected:
void dispatch(_StateInstance & instance) {
TOP & behaviour = static_cast<TOP &>(instance.specification());
(behaviour.*myHandler)();
}
Signature myHandler;
};
template<class P1, class P2, class P3, class P4, class P5, class P6, class R, class TOP>
inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3, P4, P5, P6), const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3, const typename DR<P4>::T & p4, const typename DR<P5>::T & p5, const typename DR<P6>::T & p6) {
return new _Event6<TOP, R, P1, P2, P3, P4, P5, P6>(handler, p1, p2, p3, p4, p5, p6);
}
template<class P1, class P2, class P3, class P4, class P5, class R, class TOP>
inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3, P4, P5), const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3, const typename DR<P4>::T & p4, const typename DR<P5>::T & p5) {
return new _Event5<TOP, R, P1, P2, P3, P4, P5>(handler, p1, p2, p3, p4, p5);
}
template<class P1, class P2, class P3, class P4, class R, class TOP>
inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3, P4), const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3, const typename DR<P4>::T & p4) {
return new _Event4<TOP, R, P1, P2, P3, P4>(handler, p1, p2, p3, p4);
}
template<class P1, class P2, class P3, class R, class TOP>
inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2, P3), const typename DR<P1>::T & p1, const typename DR<P2>::T & p2, const typename DR<P3>::T & p3) {
return new _Event3<TOP, R, P1, P2, P3>(handler, p1, p2, p3);
}
template<class P1, class P2, class R, class TOP>
inline IEvent<TOP> * Event(R (TOP::*handler)(P1, P2), const typename DR<P1>::T & p1, const typename DR<P2>::T & p2) {
return new _Event2<TOP, R, P1, P2>(handler, p1, p2);
}
template<class P1, class R, class TOP>
inline IEvent<TOP> * Event(R (TOP::*handler)(P1), const typename DR<P1>::T & p1) {
return new _Event1<TOP, R, P1>(handler, p1);
}
template<class R, class TOP>
inline IEvent<TOP> * Event(R (TOP::*handler)()) {
return new _Event0<TOP, R>(handler);
}
}
class _VS8_Bug_101615 {
public:
template<class S, class P1>
static inline void execute(Macho::_StateInstance & instance, const P1 & p1) {
S & behaviour = static_cast<S &>(instance.specification());
behaviour.init(p1);
}
template<class S, class P1, class P2>
static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2) {
S & behaviour = static_cast<S &>(instance.specification());
behaviour.init(p1, p2);
}
template<class S, class P1, class P2, class P3>
static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3) {
S & behaviour = static_cast<S &>(instance.specification());
behaviour.init(p1, p2, p3);
}
template<class S, class P1, class P2, class P3, class P4>
static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
S & behaviour = static_cast<S &>(instance.specification());
behaviour.init(p1, p2, p3, p4);
}
template<class S, class P1, class P2, class P3, class P4, class P5>
static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
S & behaviour = static_cast<S &>(instance.specification());
behaviour.init(p1, p2, p3, p4, p5);
}
template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
static inline void execute(Macho::_StateInstance & instance, const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
S & behaviour = static_cast<S &>(instance.specification());
behaviour.init(p1, p2, p3, p4, p5, p6);
}
};
namespace Macho {
class _Initializer {
public:
virtual ~_Initializer() {}
virtual _Initializer * clone() = 0;
virtual void destroy() { delete this; }
virtual Key adapt(Key key) { return key; }
virtual void execute(_StateInstance & instance) = 0;
};
class _StaticInitializer : public _Initializer {
virtual _Initializer * clone() { return this; }
virtual void destroy() {}
};
class _DefaultInitializer : public _StaticInitializer {
public:
virtual void execute(_StateInstance & instance) {
instance.init(false);
}
};
class _HistoryInitializer : public _StaticInitializer {
public:
virtual void execute(_StateInstance & instance) {
instance.init(true);
}
};
class _AdaptingInitializer : public _Initializer {
public:
_AdaptingInitializer(const _MachineBase & machine) : myMachine(machine) {}
virtual void execute(_StateInstance & instance) {
instance.init(true);
}
virtual _Initializer * clone() {
return new _AdaptingInitializer(myMachine);
}
virtual Key adapt(Key key);
protected:
const _MachineBase & myMachine;
};
template<class S, class P1>
class _Initializer1 : public _Initializer {
public:
_Initializer1(const P1 & p1)
: myParam1(p1)
{}
virtual _Initializer * clone() {
return new _Initializer1<S, P1>(myParam1);
}
virtual void execute(_StateInstance & instance) {
::_VS8_Bug_101615::execute<S, P1>(instance, myParam1);
}
P1 myParam1;
};
template<class S, class P1, class P2>
class _Initializer2 : public _Initializer {
public:
_Initializer2(const P1 & p1, const P2 & p2)
: myParam1(p1)
, myParam2(p2)
{}
virtual _Initializer * clone() {
return new _Initializer2<S, P1, P2>(myParam1, myParam2);
}
void execute(_StateInstance & instance) {
::_VS8_Bug_101615::execute<S, P1, P2>(instance, myParam1, myParam2);
}
P1 myParam1;
P2 myParam2;
};
template<class S, class P1, class P2, class P3>
class _Initializer3 : public _Initializer {
public:
_Initializer3(const P1 & p1, const P2 & p2, const P3 & p3)
: myParam1(p1)
, myParam2(p2)
, myParam3(p3)
{}
virtual _Initializer * clone() {
return new _Initializer3<S, P1, P2, P3>(myParam1, myParam2, myParam3);
}
void execute(_StateInstance & instance) {
::_VS8_Bug_101615::execute<S, P1, P2, P3>(instance, myParam1, myParam2, myParam3);
}
P1 myParam1;
P2 myParam2;
P3 myParam3;
};
template<class S, class P1, class P2, class P3, class P4>
class _Initializer4 : public _Initializer {
public:
_Initializer4(const P1 & p1, const P2 & p2, const P3 & p3, P4 & p4)
: myParam1(p1)
, myParam2(p2)
, myParam3(p3)
, myParam4(p4)
{}
virtual _Initializer * clone() {
return new _Initializer4<S, P1, P2, P3, P4>(myParam1, myParam2, myParam3, myParam4);
}
void execute(_StateInstance & instance) {
::_VS8_Bug_101615::execute<S, P1, P2, P3, P4>(instance, myParam1, myParam2, myParam3, myParam4);
}
P1 myParam1;
P2 myParam2;
P3 myParam3;
P4 myParam4;
};
template<class S, class P1, class P2, class P3, class P4, class P5>
class _Initializer5 : public _Initializer {
public:
_Initializer5(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5)
: myParam1(p1)
, myParam2(p2)
, myParam3(p3)
, myParam4(p4)
, myParam5(p5)
{}
virtual _Initializer * clone() {
return new _Initializer5<S, P1, P2, P3, P4, P5>(myParam1, myParam2, myParam3, myParam4, myParam5);
}
void execute(_StateInstance & instance) {
::_VS8_Bug_101615::execute<S, P1, P2, P3, P4, P5>(instance, myParam1, myParam2, myParam3, myParam4, myParam5);
}
P1 myParam1;
P2 myParam2;
P3 myParam3;
P4 myParam4;
P5 myParam5;
};
template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
class _Initializer6 : public _Initializer {
public:
_Initializer6(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6)
: myParam1(p1)
, myParam2(p2)
, myParam3(p3)
, myParam4(p4)
, myParam5(p5)
, myParam6(p6)
{}
virtual _Initializer * clone() {
return new _Initializer6<S, P1, P2, P3, P4, P5, P6>(myParam1, myParam2, myParam3, myParam4, myParam5, myParam6);
}
void execute(_StateInstance & instance) {
_VS8_Bug_101615::execute<S, P1, P2, P3, P4, P5, P6>(instance, myParam1, myParam2, myParam3, myParam4, myParam5, myParam6);
}
P1 myParam1;
P2 myParam2;
P3 myParam3;
P4 myParam4;
P5 myParam5;
P6 myParam6;
};
static _DefaultInitializer _theDefaultInitializer;
static _HistoryInitializer _theHistoryInitializer;
class _MachineBase {
public:
class Alias currentState() const;
protected:
_MachineBase();
~_MachineBase();
void setState(_StateInstance & instance, _Initializer * init);
void setState(const Alias & state);
void setPendingState(_StateInstance & instance, _Initializer * init) {
assert( (!myPendingState || (myPendingState == &instance && myPendingInit == init) ) &&
"There is already a state transition pending!");
myPendingState = &instance;
myPendingInit = init;
}
void setPendingEvent(_IEventBase * event) {
assert(event);
assert(!myPendingEvent && "There is already an event pending!");
myPendingEvent = event;
}
void rattleOn();
_StateInstance * & getInstance(ID id) {
return myInstances[id];
}
const _StateInstance * getInstance(ID id) const {
return myInstances[id];
}
void start(_StateInstance & instance);
void start(const Alias & state);
void shutdown();
void allocate(unsigned int count);
void free(unsigned int count);
void clearHistoryDeep(unsigned int count, const _StateInstance & instance);
#ifdef MACHO_SNAPSHOTS
void copy(_StateInstance ** other, unsigned int count);
_StateInstance * createClone(ID id, _StateInstance * original);
#endif
protected:
template<class C, class P>
friend class Link;
template<class T>
friend class TopBase;
friend class _StateSpecification;
friend class Alias;
friend class _AdaptingInitializer;
friend class _StateInstance;
friend class ::TestAccess;
_StateInstance * myCurrentState;
_StateInstance * myPendingState;
_Initializer * myPendingInit;
void * myPendingBox;
_IEventBase * myPendingEvent;
_StateInstance ** myInstances;
};
class Alias {
public:
explicit Alias(Key key, bool history = false)
: myStateKey(key)
, myInitializer(
history ?
static_cast<_Initializer *>(&_theHistoryInitializer)
:
static_cast<_Initializer *>(&_theDefaultInitializer)
)
{
assert(key);
}
Alias(Key key, _Initializer * init)
: myStateKey(key)
, myInitializer(init)
{
assert(key);
}
Alias(const Alias & other)
: myStateKey(other.myStateKey)
, myInitializer(other.myInitializer->clone())
{}
Alias & operator=(const Alias & other) {
if (this == &other) return *this;
myInitializer->destroy();
myStateKey = other.myStateKey;
myInitializer = other.myInitializer->clone();
return *this;
}
~Alias() {
myInitializer->destroy();
}
operator Key() const {
return key();
}
bool isChild(Key k) const {
return key()->childPredicate(k);
}
bool isParent(Key k) const {
return static_cast<_KeyData *>(k)->childPredicate(key());
}
const char * name() const {
return key()->name();
}
ID id() const {
return key()->id;
}
protected:
friend class _MachineBase;
friend class _StateSpecification;
void setState(_MachineBase & machine) const;
_KeyData * key() const { return static_cast<_KeyData *>(myInitializer->adapt(myStateKey)); }
protected:
Key myStateKey;
_Initializer * myInitializer;
};
typedef Alias StateAlias;
template<class S>
Alias State() {
return Alias(S::key());
}
template<class S, class P1>
Alias State(const P1 & p1) {
return Alias(S::key(), new _Initializer1<S, P1>(p1));
}
template<class S, class P1, class P2>
Alias State(const P1 & p1, const P2 & p2) {
return Alias(S::key(), new _Initializer2<S, P1, P2>(p1, p2));
}
template<class S, class P1, class P2, class P3>
Alias State(const P1 & p1, const P2 & p2, const P3 & p3) {
return Alias(S::key(), new _Initializer3<S, P1, P2, P3>(p1, p2, p3));
}
template<class S, class P1, class P2, class P3, class P4>
Alias State(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
return Alias(S::key(), new _Initializer4<S, P1, P2, P3, P4>(p1, p2, p3, p4));
}
template<class S, class P1, class P2, class P3, class P4, class P5>
Alias State(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
return Alias(S::key(), new _Initializer5<S, P1, P2, P3, P4, P5>(p1, p2, p3, p4, p5));
}
template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
Alias State(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
return Alias(S::key(), new _Initializer6<S, P1, P2, P3, P4, P5, P6>(p1, p2, p3, p4, p5, p6));
}
template<class S>
Alias StateHistory(const _MachineBase & machine) {
return Alias(S::key(), new _AdaptingInitializer(machine));
}
#ifdef MACHO_SNAPSHOTS
template<class TOP>
class Snapshot : public _MachineBase {
public:
Snapshot(Machine<TOP> & machine);
~Snapshot() {
free(Machine<TOP>::theStateCount);
}
private:
friend class Machine<TOP>;
Snapshot(const Snapshot<TOP> & other);
Snapshot & operator=(const Snapshot<TOP> & other);
};
#endif
template<class TOP>
class Machine : public _MachineBase {
public:
struct AfterAdvice {
AfterAdvice(Machine<TOP> & m) : myMachine(m) {}
~AfterAdvice() { myMachine.rattleOn(); }
TOP * operator->() {
return static_cast<TOP *>(& (myMachine.myCurrentState->specification()) );
}
private:
Machine<TOP> & myMachine;
};
Machine(typename TOP::Box * box = 0) {
typedef typename _SameType<TopBase<TOP>, typename TOP::SUPER>::Check MustDeriveFromTopBase;
allocate(theStateCount);
_StateInstance & top = TOP::_getInstance(*this);
top.setBox(box);
start(top);
}
Machine(const Alias & state, typename TOP::Box * box = 0) {
typedef typename _SameType<TopBase<TOP>, typename TOP::SUPER>::Check MustDeriveFromTopBase;
allocate(theStateCount);
_StateInstance & top = TOP::_getInstance(*this);
top.setBox(box);
start(state);
}
#ifdef MACHO_SNAPSHOTS
Machine(const Snapshot<TOP> & snapshot) {
allocate(theStateCount);
copy(snapshot.myInstances, theStateCount);
}
Machine<TOP> & operator=(const Snapshot<TOP> & snapshot) {
assert(!myPendingState);
assert(!myPendingEvent);
myCurrentState->shutdown();
free(theStateCount);
copy(snapshot.myInstances, theStateCount);
myCurrentState = getInstance(0);
_StateInstance * current = getInstance(snapshot.myCurrentState->id());
current->restore(*current);
rattleOn();
return *this;
}
#endif
~Machine() {
myCurrentState->shutdown();
free(theStateCount);
}
AfterAdvice operator->() {
assert(myCurrentState);
assert(!myPendingState);
return AfterAdvice(*this);
}
void dispatch(IEvent<TOP> * event, bool destroy = true) {
assert(event);
event->dispatch(*myCurrentState);
if (destroy) delete event;
rattleOn();
}
const typename TOP::Box & box() const {
assert(myCurrentState);
return static_cast<TOP &>(myCurrentState->specification()).TOP::box();
}
private:
template<class C, class P>
friend class Link;
private:
Machine(const Machine<TOP> & other);
Machine<TOP> & operator=(const Machine<TOP> & other);
#ifdef MACHO_SNAPSHOTS
friend class Snapshot<TOP>;
#endif
template<class T> friend class StateID;
static ID theStateCount;
};
template<class TOP>
ID Machine<TOP>::theStateCount = 1;
template<class S>
const ID StateID<S>::value = Machine<typename S::TOP>::theStateCount++;
template<class S>
inline void _StateSpecification::setState() {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, &_theDefaultInitializer);
}
template<class S, class P1>
inline void _StateSpecification::setState(const P1 & p1) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, new _Initializer1<S, P1>(p1));
}
template<class S, class P1, class P2>
inline void _StateSpecification::setState(const P1 & p1, const P2 & p2) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, new _Initializer2<S, P1, P2>(p1, p2));
}
template<class S, class P1, class P2, class P3>
inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, new _Initializer3<S, P1, P2, P3>(p1, p2, p3));
}
template<class S, class P1, class P2, class P3, class P4>
inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, new _Initializer4<S, P1, P2, P3, P4>(p1, p2, p3, p4));
}
template<class S, class P1, class P2, class P3, class P4, class P5>
inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, new _Initializer5<S, P1, P2, P3, P4, P5>(p1, p2, p3, p4, p5));
}
template<class S, class P1, class P2, class P3, class P4, class P5, class P6>
inline void _StateSpecification::setState(const P1 & p1, const P2 & p2, const P3 & p3, const P4 & p4, const P5 & p5, const P6 & p6) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, new _Initializer6<S, P1, P2, P3, P4, P5, P6>(p1, p2, p3, p4, p5, p6));
}
template<class S>
inline void _StateSpecification::setStateHistory() {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.setPendingState(instance, &_theHistoryInitializer);
}
template<class S>
inline void _StateSpecification::setStateBox(typename S::Box * box) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.myPendingBox = box;
m.setPendingState(instance, &_theHistoryInitializer);
}
template<class S>
inline void _StateSpecification::setStateDirect(typename S::Box * box) {
_MachineBase & m = _myStateInstance.machine();
_StateInstance & instance = S::_getInstance(m);
m.myPendingBox = box;
m.setPendingState(instance, &_theDefaultInitializer);
}
template<class T>
inline void TopBase<T>::dispatch(IEvent<TOP> * event) {
assert(event);
_myStateInstance.machine().setPendingEvent(event);
}
template<class T>
inline _MachineBase & TopBase<T>::machine() {
return this->_myStateInstance.machine();
}
template<class C, class P>
inline Link<C, P>::Link(_StateInstance & instance)
: P(P::_getInstance(instance.machine()))
, _myStateInstance(instance)
{}
template<class C, class P>
inline void * Link<C, P>::_box() {
return _myStateInstance.box();
}
template<class C, class P>
inline void Link<C, P>::_deleteBox(_StateInstance & instance) {
instance.deleteBox();
}
template<class C, class P>
inline _StateInstance & Link<C, P>::_getInstance(_MachineBase & machine) {
_StateInstance * & instance = machine.getInstance(StateID<C>::value);
if (!instance)
instance = new _SubstateInstance<C>(machine, &P::_getInstance(machine));
return *instance;
}
template<class C, class P>
inline bool Link<C, P>::isCurrent(const _MachineBase & machine) {
return machine.currentState().isChild(key());
}
template<class C, class P>
inline bool Link<C, P>::isCurrentDirect(const _MachineBase & machine) {
return key() == machine.currentState();
}
template<class C, class P>
void Link<C, P>::clearHistory(_MachineBase & machine) {
const _StateInstance * instance = machine.getInstance(StateID<C>::value);
if (instance)
instance->setHistory(0);
}
template<class C, class P>
void Link<C, P>::clearHistoryDeep(_MachineBase & machine) {
const _StateInstance * instance = machine.getInstance(StateID<C>::value);
if (instance)
machine.clearHistoryDeep(Machine<TOP>::theStateCount, *instance);
}
template<class C, class P>
Alias Link<C, P>::history(const _MachineBase & machine) {
const _StateInstance * instance = machine.getInstance(StateID<C>::value);
_StateInstance * history = 0;
if (instance)
history = instance->history();
return Alias(history ? history->key() : key());
}
template<class C, class P>
inline Key Link<C, P>::key() {
static _KeyData k = { _getInstance, isChild, C::_state_name, StateID<C>::value };
return &k;
}
template<class C, class P>
inline Alias Link<C, P>::alias() {
return Alias(key());
}
#ifdef MACHO_SNAPSHOTS
template<class TOP>
Snapshot<TOP>::Snapshot(Machine<TOP> & machine) {
assert(!machine.myPendingState);
assert(!machine.myPendingEvent);
assert(machine.myCurrentState);
allocate(Machine<TOP>::theStateCount);
copy(machine.myInstances, Machine<TOP>::theStateCount);
myCurrentState = getInstance(machine.myCurrentState->id());
}
#endif
}
#endif