[openrtm-commit:02022] r2763 - in branches/FSM4RTC/OpenRTM-aist/src/lib: . hrtm hrtm/idls rtm

openrtm @ openrtm.org openrtm @ openrtm.org
2016年 10月 7日 (金) 10:32:30 JST


Author: n-ando
Date: 2016-10-07 10:32:30 +0900 (Fri, 07 Oct 2016)
New Revision: 2763

Added:
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/component_manager.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/data_flow_component.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/defs.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/BasicDataType.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/ExtendedDataTypes.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/HRTM.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/in_port.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/logger.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/out_port.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/statechart.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/utils.h
   branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/version.h
Modified:
   branches/FSM4RTC/OpenRTM-aist/src/lib/Makefile.am
   branches/FSM4RTC/OpenRTM-aist/src/lib/rtm/Makefile.am
Log:
[FSM4RTC,2.0] Some dummy headers have been added for HRTM porting.

Modified: branches/FSM4RTC/OpenRTM-aist/src/lib/Makefile.am
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/Makefile.am	2016-10-06 06:25:12 UTC (rev 2762)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/Makefile.am	2016-10-07 01:32:30 UTC (rev 2763)
@@ -5,4 +5,4 @@
 ## $Id$
 ##---------------------------------------------------------------------------
 
-SUBDIRS = coil rtm
+SUBDIRS = coil rtm hrtm

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/component_manager.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/component_manager.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/component_manager.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,120 @@
+#ifndef HRTM_COMPONENT_MANAGER_H
+#define HRTM_COMPONENT_MANAGER_H
+
+#include <rtm/Manager.h>
+#include <rtm/Factory.h>
+#include <rtm/RTObject.h>
+#include <coil/Guard.h>
+#include <coil/Mutex.h>
+//#include <hrtm/data_flow_component.h>
+#include <hrtm/logger.h>
+
+namespace hrtm
+{
+  class DataFlowComponent;
+
+
+  template <class _New>
+  RTC::RTObject_impl* Create(RTC::Manager* manager)
+  {
+    return new _New();
+  }
+
+  template <class _Delete>
+  void Delete(RTC::RTObject_impl* rtc)
+  {
+    delete rtc;
+  }
+  class ComponentManager;
+  typedef void (*ModuleInitProc)(hrtm::ComponentManager*);
+//  class MyModuleInit
+//  {
+//    ModuleInitProc m_initProc;
+//  public:
+//    MyModuleInit(ModuleInitProc proc)
+//      : m_initProc(proc)
+//    {
+//    }
+//    void operator()(RTC::Manager* mgr)
+//    {
+//      m_initProc(dynamic_cast<hrtm::ComponentManager*>(mgr));
+//    }
+//  };
+//  ModuleInitProc g_m;
+//  void Proc(RTC::Manager* mgr)
+//  {
+//    g_m(dynamic_cast<hrtm::ComponentManager*>(mgr));
+//  }
+
+  //void ModuleInit(hrtm::ComponentManager* manager)
+  
+  class ComponentManager
+    : public RTC::Manager
+  {
+    typedef coil::Mutex Mutex;
+    typedef coil::Guard<Mutex> Guard;
+  public:
+    template<typename CompType>
+    bool regist(coil::Properties* profile,  const char*, const char*)
+    {
+      return RTC::Manager::
+        registerFactory(*profile,
+                        (RTC::RtcNewFunc)hrtm::Create<CompType>,
+                        (RTC::RtcDeleteFunc)hrtm::Delete<CompType> );
+    }
+
+    virtual DataFlowComponent* create_component(const char* component_name)
+    {
+      return NULL; // createComponent(component_name);
+    }
+    static void init_proc(RTC::Manager* mgr)
+    {
+      ::hrtm::ComponentManager::initProc(manager);
+    }
+    virtual void set_init_proc(void(*init_proc)(hrtm::ComponentManager*))
+    {
+      initProc = init_proc;
+      setModuleInitProc(hrtm::ComponentManager::init_proc);
+    }
+    virtual bool activate()
+    {
+      return activateManager();
+    }
+    virtual void run(bool non_block = false)
+    {
+      runManager(non_block);
+    }
+    static ComponentManager& instance(int argc, char** argv)
+    {
+      // DCL for singleton
+      if (!manager)
+        {
+          Guard guard(mutex);
+          if (!manager)
+            {
+              manager = new ComponentManager();
+              manager->initManager(argc, argv);
+              manager->initLogger();
+              manager->initORB();
+              manager->initNaming();
+              manager->initFactories();
+              manager->initExecContext();
+              manager->initComposite();
+              manager->initTimer();
+              manager->initManagerServant();
+            }
+        }
+      return *manager;
+    }
+  protected:
+    ComponentManager()
+      : RTC::Manager()
+    {
+    }
+    static ModuleInitProc initProc;
+    static ComponentManager* manager;
+    static coil::Mutex mutex;
+  };
+};
+
+#endif // HRTM_COMPONENT_MANAGER_H


Property changes on: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/component_manager.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/data_flow_component.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/data_flow_component.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/data_flow_component.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,44 @@
+#ifndef HRTM_DATA_FLOW_COMPONENT_H
+#define HRTM_DATA_FLOW_COMPONENT_H
+
+#include <rtm/DataFlowComponentBase.h>
+#include <hrtm/component_manager.h>
+#include <hrtm/defs.h>
+#include <hrtm/in_port.h>
+
+namespace RTC
+{
+  enum StatusKind
+    {
+      FSM_STATUS
+    };
+};
+namespace hrtm
+{
+#define COMPONENT_NAME(comp_name) #comp_name
+
+  //  typedef RTC::DataFlowComponent DataFlowComponent;
+  //  using DataFlowComponent = RTC::DataFlowComponentBase;
+  class DataFlowComponent
+    : public RTC::DataFlowComponentBase
+  {
+  public:
+    DataFlowComponent()
+      : RTC::DataFlowComponentBase(&RTC::Manager::instance())
+    {
+    }
+//    DataFlowComponent(RTC::Manager* mgr)
+//      : RTC::DataFlowComponentBase(mgr)
+//    {
+//    }
+    virtual RTC::ReturnCode_t initialize(hrtm::ComponentManager* mgr)
+    {
+      return RTC::RTC_OK;
+    }
+    void updateFsmStatus(RTC::StatusKind status_kind, const char* state)
+    {
+    }
+  };
+};
+
+#endif // HRTM_DATA_FLOW_COMPONENT_H


Property changes on: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/data_flow_component.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/defs.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/defs.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/defs.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,179 @@
+// vim:sw=2 ts=2 expandtab fileencoding=utf-8
+/**
+ * \file defs.h
+ * \brief システム共用マクロ集
+ *
+ * Copyright 2010 Honda R&D Co.,Ltd.
+ */
+
+#ifndef HRTM_DEFS_H_
+#define HRTM_DEFS_H_
+
+
+#ifdef _MSC_VER
+#ifdef HRTM_DLL
+#ifdef HRTM_EXPORTS
+#define EXPORT_DLL __declspec(dllexport)
+#ifndef EXTERN
+#define EXTERN
+#endif
+#else
+#define EXPORT_DLL __declspec(dllimport)
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+#endif
+#else
+#define EXPORT_DLL
+#ifndef EXTERN
+#define EXTERN
+#endif
+#endif
+#else
+#define EXPORT_DLL
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+#endif
+
+#ifdef _MSC_VER
+#define __attribute__(attribute)
+#else
+#ifndef __pragma
+#define __pragma(x)
+#endif
+#endif
+
+#ifdef WIN32
+
+#  ifdef ORBEXPRESS
+#    pragma comment(lib, "OEbridge")
+#    pragma comment(lib, "OEipmc")
+#    pragma comment(lib, "OEmirror")
+#    pragma comment(lib, "OEorb")
+#    pragma comment(lib, "OErudp")
+#    pragma comment(lib, "OEshrmem")
+#    pragma comment(lib, "OEtcp")
+#    pragma comment(lib, "OEtcpv6")
+#    pragma comment(lib, "OEudp")
+#  else
+#    ifdef _WINSTATIC
+#      ifdef NDEBUG
+#        pragma comment(lib, "omniORB4")
+#        pragma comment(lib, "omnithread")
+#        pragma comment(lib, "omniDynamic4")
+#      else
+#        pragma comment(lib, "omniORB4d")
+#        pragma comment(lib, "omnithreadd")
+#        pragma comment(lib, "omniDynamic4d")
+#      endif
+#      pragma comment(lib, "ws2_32")
+#      pragma comment(lib, "advapi32")
+#    else
+#      ifdef NDEBUG
+#        pragma comment(lib, "omniORB4_rt")
+#        pragma comment(lib, "omnithread_rt")
+#        pragma comment(lib, "omniDynamic4_rt")
+#      else
+#        pragma comment(lib, "omniORB4_rtd")
+#        pragma comment(lib, "omnithread_rtd")
+#        pragma comment(lib, "omniDynamic4_rtd")
+#      endif
+#    endif
+#  endif
+#  if !defined(HRTM_NO_AUTOMATIC_LINK) && !defined(HRTM_EXPORTS)
+#    if defined(HRTM_STATIC)
+#      if defined(NDEBUG)
+#        pragma comment(lib, "HRTMmd")
+#      else
+#        pragma comment(lib, "HRTMmdd")
+#      endif
+#    else
+#      if defined(NDEBUG)
+#        pragma comment(lib, "HRTM")
+#      else
+#        pragma comment(lib, "HRTMd")
+#      endif
+#    endif
+#  endif
+#endif
+
+
+
+/**
+ * \def IF_WIN32
+ * \brief Windows の時だけコードを実行する
+ */
+#ifdef _WIN32
+#define IF_WIN32(sentence) sentence
+#else
+#define IF_WIN32(sentence)
+#endif
+
+/**
+ * \def IF_MSC_VER
+ * \brief VC の時だけコードを実行する
+ */
+#ifdef _MSC_VER
+#define IF_MSC_VER(sentence) sentence
+#else
+#define IF_MSC_VER(sentence)
+#endif
+
+/**
+ * \def IF__GNUC__
+ * \brief GNU C の時だけコードを実行する
+ */
+#ifdef __GNUC__
+#define IF__GNUC__(sentence) sentence
+#else
+#define IF__GNUC__(sentence)
+#endif
+
+/**
+ * \def IF__GNUG__
+ * \brief GNU C++ の時だけコードを実行する
+ */
+#ifdef __GNUG__
+#define IF__GNUG__(sentence) sentence
+#else
+#define IF__GNUG__(sentence)
+#endif
+
+/**
+ * \def IF__linux
+ * \brief Linux の時だけコードを実行する
+ */
+#if defined(linux) || defined(__linux) || defined(__linux__)
+#define IF__linux(sentence) sentence
+#else
+#define IF__linux(sentence)
+#endif
+
+/**
+ \~Japanese
+ \brief class \a TypeName の複製構築子と,代入演算子のダミー宣言
+ \~English
+ \brief Dummy declarations of copy constructor and assign operator.
+*/
+#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
+  TypeName(const TypeName&);               \
+  TypeName& operator=(const TypeName&)
+
+
+namespace coil
+{
+  class Properties;
+};
+namespace hrtm
+{
+  namespace utils
+  {
+    using Properties = coil::Properties;
+  };
+};
+
+//#ifndef hrtm
+//#define hrtm RTC
+//#endif // hrtmcomp
+#endif  // HRTM_DEFS_H_


Property changes on: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/defs.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/BasicDataType.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/BasicDataType.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/BasicDataType.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1 @@
+#include <rtm/idl/BasicDataTypeSkel.h>

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/ExtendedDataTypes.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/ExtendedDataTypes.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/ExtendedDataTypes.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,2 @@
+#include <rtm/idl/ExtendedDataTypesSkel.h>
+

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/idls/HRTM.h
===================================================================
Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/in_port.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/in_port.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/in_port.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,7 @@
+#include <rtm/InPort.h>
+
+namespace hrtm
+{
+  template <class DataType>
+  using InPort = RTC::InPort<DataType>;
+};


Property changes on: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/in_port.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/logger.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/logger.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/logger.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,31 @@
+#ifndef HRTM_LOGGER_H
+#define HRTM_LOGGER_H
+
+#include <rtm/SystemLogger.h>
+
+#define HRTM_ERROR(name, text)
+//#define HRTM_ERROR_STR RTC_ERROR_STR
+#define HRTM_WARN(name, text)
+#define HRTM_WARN_STR RTC_WARN_STR
+#define HRTM_NORMAL(name, text)
+#define HRTM_NORMAL_STR RTC_NORMAL_STR
+#define HRTM_INFO(name, text)
+#define HRTM_INFO_STR RTC_INFO_STR
+#define HRTM_DEBUG(name, text)
+#define HRTM_DEBUG_STR RTC_DEBUG_STR
+#define HRTM_TRACE(name, text)
+#define HRTM_TRACE_STR RTC_TRACE_STR
+#define HRTM_VERBOSE(name, text)
+#define HRTM_VERBOSE_STR RTC_VERBOSE_STR
+#define HRTM_PARANOID(name, text)
+#define HRTM_PARANOID_STR RTC_PARANOID_STR
+
+namespace hrtm
+{
+  namespace utils
+  {
+    using Logger = RTC::Logger;
+  };
+};
+#endif // HRTM_LOGGER_H
+


Property changes on: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/logger.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/out_port.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/out_port.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/out_port.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,7 @@
+#include <rtm/OutPort.h>
+
+namespace hrtm
+{
+  template<class DataType>
+  using OutPort = RTC::OutPort<DataType>;
+};


Property changes on: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/out_port.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/statechart.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/statechart.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/statechart.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,1022 @@
+/*
+ * Copyright 2005 by Eduard Hiti.
+*/
+#ifndef HRTM_STATECHART_H_
+#define HRTM_STATECHART_H_
+
+#define SC_TRACE
+
+#include <cassert>
+#include <iostream>  // NOLINT
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <string>
+#include "hrtm/defs.h"
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable:4512 4251)
+#elif defined(__GNUC__) && (__GNUC_MINOR__ >= 6)
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+////////////////////////////////////////////////////////////////////////////////
+// Various macros for state and history declaration
+
+// Use this macro to define your top state class.
+#define TOPSTATE(TOP) \
+  struct TOP : public hrtm::sc::Link< TOP, hrtm::sc::TopState< TOP > >
+
+// Use this macro for all your other state classes.
+#define SUBSTATE(STATE, SUPERSTATE) \
+  struct STATE : public hrtm::sc::Link< STATE, SUPERSTATE >
+
+// Use this macro in your class definition to give it state functionality
+// (mandatory). If you have a state data declare it BEFORE macro invocation!
+#define STATE(S) \
+  public: \
+  /* Constructor and destructor already defined: */ \
+  /* you can't (and shouldn't) have your own! */ \
+  /* For the user a state class "constructor" and */ \
+  /* "destructor" are its entry and exit method! */ \
+  S(hrtm::sc::StateInfo & info) : hrtm::sc::Link<S, SUPER>(info) { \
+          /* Compile time check: S must derive directly from Link<S, SUPER> */ \
+          hrtm::sc::Link<S, SUPER> * p = 0; \
+          LinkType * p2 = 0; \
+          p = p2; \
+          p2 = p; \
+  } \
+  ~S() {} \
+  static const char * state_name() { return #S; } \
+  /* Get to your Data with this method: */ \
+  Data & data() { return *static_cast<Data *>(local_data()); } \
+
+// Use this macro to select deep history strategy.
+#define DEEPHISTORY() \
+  private: \
+  /* If no superstate has history, SUPER::set_history_super is a NOOP */ \
+  void save_history(hrtm::sc::StateInfo & self, \
+      hrtm::sc::StateInfo & /* shallow */, hrtm::sc::StateInfo & deep) { \
+    self.set_history(&deep); \
+    SUPER::set_history_super(self, deep); } \
+  protected: \
+  /* Substates may use set_history_super to bubble up history */ \
+  void set_history_super(\
+      hrtm::sc::StateInfo & self, hrtm::sc::StateInfo & deep) \
+  { self.set_history_super(deep); } \
+ public:
+// Use this macro to select shallow history strategy.
+#define HISTORY() \
+  private: \
+  /* If no superstate has history, SUPER::set_history_super is a NOOP */ \
+  void save_history(hrtm::sc::StateInfo & self, hrtm::sc::StateInfo & shallow, \
+      hrtm::sc::StateInfo & deep) { \
+    self.set_history(&shallow); \
+    SUPER::set_history_super(self, deep); } \
+  protected: \
+  /* Substates may use set_history_super to bubble up history */ \
+  void set_history_super(\
+      hrtm::sc::StateInfo & self, hrtm::sc::StateInfo & deep) \
+  { self.set_history_super(deep); } \
+ public:
+// Use this macro to have dataes survive state transitions
+#define PERSISTENT() \
+  private:  \
+  void delete_data(hrtm::sc::StateInfo & info) {} \
+ public:
+namespace hrtm {
+namespace sc {
+
+typedef unsigned int Key;
+
+class MachineBase;
+
+template<class T>
+class Machine;
+
+template<class T>
+class EventParamBase;
+
+class StateInfo;
+
+template<class T>
+class TopState;
+
+template<class S>
+class State;
+
+////////////////////////////////////////////////////////////////////////////////
+// Data for states which don't declare own Data class.
+class EmptyData {
+ public:
+  EmptyData() {}
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Each state machine has its own key generator. The generator returns unique
+// identifiers. The identifiers are consecutive integers starting from zero,
+// which allows use as index into a vector for fast access.
+// Root always has zero as key.
+template<class TOP>
+struct KeyInit {
+  KeyInit() : key(Machine<TOP>::the_state_count_++) {}
+  Key key;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Base class for all state classes.
+// Also serves as 'Root' state. By entering this state we trigger entry
+// and exit actions of user's top state.
+class EXPORT_DLL StateBase {
+ public:
+  virtual ~StateBase() {}
+
+  // Get unique name of state.
+  static Key key() {
+    return 0;
+  }
+
+ protected:
+  StateBase(StateInfo & info)  // NOLINT
+     : state_info_(info) {}
+
+  // Restore from snapshot event: set current state.
+  // Default implementation: Does not trigger entry actions!
+  virtual void restore(StateInfo & current);
+  // Shutdown machine event: exit all states.
+  // Default implementation: Triggers exit actions!
+  // Override empty to omit calling exit actions.
+  virtual void shutdown();
+  // This is the method to bubble up history information
+  // for states whose superstates have no history (so does nothing).
+  virtual void set_history_super(
+      StateInfo & /* self */, StateInfo & /* deep */) {}
+
+ protected:
+  // State entry. Not allowed to initiate state change.
+  virtual void on_entry() {}
+  // Special kind of state entry: Upon transition to a new state,
+  // entry methods of that state and its superstates are called;
+  // 'init' however is called only on the one state the transition
+  // actually goes to.
+  // Is allowed to change state.
+  virtual void on_init() {}
+  // State exit. Not allowed to initiate state change.
+  virtual void on_exit() {}
+
+ protected:
+  // C++ needs something like package visibility
+  friend class StateInfo;
+  friend class RootStateInfo;
+  friend class MachineBase;
+
+  // Create StateInfo object of state.
+  static StateInfo & get_info(MachineBase & machine);
+  virtual void delete_data(StateInfo & /* info */) {}
+  // Default history strategy (no history).
+  virtual void save_history(StateInfo & /* self */, StateInfo & /* shallow */,
+      StateInfo & /* deep */) {}
+
+ protected:
+  StateInfo & state_info_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Base class for user defined top state (and indirectly all other states).
+template<class T>
+class TopState : public StateBase {
+ public:
+  // This typedef is an alias for user defined top state in all (sub)states.
+  typedef T TOP;
+
+ protected:
+  TopState(StateInfo & info) : StateBase(info) {}  // NOLINT
+
+  void dispatch(EventParamBase<TOP> * event);
+
+  void defer(EventParamBase<TOP> * event, const std::string& name="event");
+
+  // Returns current state machine instance.
+  Machine<TOP> & machine() {
+    return *static_cast<Machine<TOP> *>(&this->state_info_.machine());
+  }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper classes to allow parametrization of state transitions with 'set_state'
+// (also for starting machines).
+
+// Members of do-it-yourself virtual function table.
+typedef StateInfo & (*GetInfoFn)(MachineBase & machine);
+typedef void (*DestroyFn)(void * data);
+typedef void * (*CloneFn)(void * data);
+
+// DIY virtual function table.
+struct StateCharacter {
+  GetInfoFn get_info;
+  DestroyFn destroy;
+  CloneFn clone;
+};
+
+// This is the base class for state aliases. A state alias represents a
+// state of a machine. A transition to that state can be initiated by
+// giving the alias object to the 'set_state' method.
+//
+// State aliases are created by the template class 'State' further below.
+//
+// Objects of this types are copyable; however, on copying the copy
+// actually takes over the data instance of the original object.
+// This also happens when the alias object is used for a state transition:
+// the alias' data instance is used up by the reached state; the next time
+// the same alias is used for a state transition no data is provided
+// anymore!
+//
+// To keep the dataes of alias objects you need to clone the object with the
+// 'clone' method: for this to work however dataes need to be copyable (have
+// a copy constructor).
+// Define MACRO_DATA_COPY when compiling if this is the case!
+//
+// This class has no virtual functions but something similar in form of
+// pointers to static functions (static functions suffice since the
+// operations depend only on template parameters).      This crazy stuff is
+// done here because this way allocating memory on the heap when cloning
+// state aliases can be avoided, which we would have to do with ordinary
+// virtual methods. SPEED!!!
+class StateAlias {
+ public:
+  // Takes over data from other object!
+  // If you do not want this use 'clone'!
+  StateAlias(const StateAlias & other)
+    : data_(other.take_data())
+    , character_(other.character_) {}
+
+  // Takes over data from other object!
+  // If you do not want this use 'clone'!
+  StateAlias & operator=(const StateAlias & other) {
+    (character_->destroy)(data_);
+    character_ = other.character_;
+    data_ = other.take_data();
+    return *this;
+  }
+  ~StateAlias() {
+    (character_->destroy)(data_);
+  }
+  // Clones object.
+  // Will call copy constructor of data.
+  StateAlias clone() {
+    return StateAlias(character_, data_ ? (character_->clone)(data_) : 0);
+  }
+  StateInfo & get_info(MachineBase & machine) const {
+    return (character_->get_info)(machine);
+  }
+  // Hand over data object (to state instances or other state aliases).
+  void * take_data() const {
+    void * data = data_;
+    data_ = 0;
+    return data;
+  }
+
+ protected:
+  // Protected constructor: User creates alias with the 'State' class below.
+  StateAlias(StateCharacter * character, void * data)
+    : data_(data)
+    , character_(character) {}
+
+ private:
+  mutable void * data_;
+  // DIY virtual function table.
+  StateCharacter * character_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// This class links substates to superstates by deriving from the superstate
+// and being derived from by the substate.
+// Substates inherit event handlers from superstates for reuse or redefinition
+// this way.
+template<class C, class P>
+class Link : public P {
+ public:
+  // Alias for superstate.
+  typedef P SUPER;
+  // Alias for topstate.
+  typedef typename P::TOP TOP;
+  // Default data type.
+  typedef EmptyData Data;
+
+  // Get unique key of state.
+  static Key key() {
+    return the_key_.key;
+  }
+  // Is machine m in this state?
+  static bool is_current(Machine<TOP> & m) {
+    return m.is_current(get_info(m));
+  }
+  // Is machine m in exactly this state?
+  static bool is_current_direct(Machine<TOP> & m) {
+    return m.is_current_direct(get_info(m));
+  }
+  static void clear_history(Machine<TOP> & m) { get_info(m).set_history(0); }
+  static void clear_history_deep(Machine<TOP> & m) {
+    m.clear_history_deep(get_info(m)); }
+  static void set_state(Machine<TOP> & machine, void * data = 0) {
+    StateInfo & info = get_info(machine);
+    machine.set_pending_state(info, true, data);
+  }
+  static void set_state_direct(Machine<TOP> & machine, void * data = 0) {
+    StateInfo & info = get_info(machine);
+    machine.set_pending_state(info, false, data);
+  }
+  // Initiate transition to a new state.
+  // Parameter state is the new state to enter.
+  // See above and class State for more information.
+  void set_state(const StateAlias & state) {
+    StateInfo & info = state.get_info(P::machine());
+    P::machine().set_pending_state(info, true, state.take_data());
+  }
+  void set_state_direct(const StateAlias & state) {
+    StateInfo & info = state.get_info(P::machine());
+    P::machine().set_pending_state(info, true, state.take_data());
+  }
+  // to be used with restore
+  void set_state(StateInfo & current, void * data = 0) {
+    this->state_info_.machine().set_pending_state(current, true, data);
+  }
+
+ protected:
+  // Needed to perform compile time checks.
+  typedef Link<C, P> LinkType;
+
+  Link(StateInfo & info);  // NOLINT
+  // These definitions seem redundant but they are not!
+  // They override parent definitions so each substate gets either
+  // this default or their own, but never its parents definitions.
+  virtual void on_entry() {}
+  virtual void on_init() {}
+  virtual void on_exit() {}
+  // Create StateInfo object of state.
+  static StateInfo & get_info(MachineBase & machine);
+  // Data is by default not persistent. Not redundant!
+  void delete_data(StateInfo & info);
+  // Default history strategy (no history). Not redundant!
+  void save_history(
+      StateInfo & self, StateInfo & /* shallow */, StateInfo & deep) {
+    // Bubble up history. If no superstate has history,
+    // set_history_super will do nothing.
+    this->set_history_super(self, deep);
+  }
+  // This method keeps 'state_info_' attribute private.
+  void * local_data();
+
+ protected:
+  // for get_info
+  friend class StateBase;
+  // for get_info
+  friend class Machine<TOP>;
+  friend class State<C>;
+
+ protected:
+  StateInfo & state_info_;
+  static KeyInit<TOP> the_key_;
+};
+
+template<class C, class P> KeyInit<typename P::TOP> Link<C, P>::the_key_;
+
+////////////////////////////////////////////////////////////////////////////////
+// StateInfo describes a state. Keeps history, data and state object for state.
+// StateInfo object is created the first time state is entered.
+// There is at most one StateInfo object per state per machine instance.
+class EXPORT_DLL StateInfo {
+ public:
+  StateInfo(MachineBase & machine, StateInfo * parent);
+  virtual ~StateInfo();
+  // Perform entry actions.
+  // 'first' is true on very first call.
+  void on_entry(StateInfo & previous, bool first = true);
+  // Perform exit actions.
+  void on_exit(StateInfo & next);
+  // Perform init action.
+  void on_init(bool history);
+  void save_history(StateInfo & shallow, StateInfo & deep) {
+    // Check state's history strategy.
+    instance_->save_history(*this, shallow, deep);
+  }
+  // Update superstate's history information:
+  void set_history_super(StateInfo & deep) {
+    if (parent_) {
+      // Let it choose between deep or shallow history.
+      parent_->save_history(*this, deep);
+    }
+  }
+  // Data has been created explicitly.
+  void set_data(void * data) {
+    assert(!data_);
+
+    if (data_place) {
+      // Free cached memory of previously used data.
+      ::operator delete(data_place);
+      data_place = 0;
+    }
+    data_ = data;
+  }
+  // Copy state of another StateInfo object.
+  void copy(StateInfo & original);
+  // Create a clone of StateInfo object for another machine.
+  StateInfo * clone(MachineBase & new_machine);
+  virtual void clone_data(void * data) = 0;
+  void shutdown() {
+    instance_->shutdown();
+  }
+  void restore(StateInfo & info) {
+    instance_->restore(info);
+  }
+  virtual Key key() = 0;
+  // 'Virtual constructor' needed for cloning.
+  virtual StateInfo * create(MachineBase & machine, StateInfo * parent) = 0;
+  virtual void create_data() = 0;
+  virtual void delete_data() = 0;
+  virtual const char * name() const = 0;
+  // Is 'state' a superstate?
+  bool is_child(StateInfo & state) const {
+    return this == &state || (parent_ && parent_->is_child(state));
+  }
+  StateBase & instance() {
+    assert(instance_);
+    return *instance_;
+  }
+  void * data() {
+    assert(data_);
+    return data_;
+  }
+  MachineBase & machine() {
+    return machine_;
+  }
+  void set_history(StateInfo * history) {
+    history_ = history;
+  }
+
+ protected:
+  MachineBase & machine_;
+  StateBase * instance_;   // Instance of state class
+  StateInfo * history_;
+  StateInfo * parent_;
+  void * data_;
+  void * data_place;      // Reused data memory
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// StateInfo for Root state.
+class RootStateInfo : public StateInfo {
+ public:
+  RootStateInfo(MachineBase & machine, StateInfo * parent)
+    : StateInfo(machine, parent) {
+    instance_ = new StateBase(*this);
+  }
+  virtual Key key() {
+    return 0;
+  }
+
+  virtual void create_data() {}
+  virtual void delete_data() {}
+  virtual void clone_data(void * /* data */) {}
+  virtual const char * name() const { return "Root"; }
+  // 'Virtual constructor' needed for cloning.
+  virtual StateInfo * create(MachineBase & machine, StateInfo * parent) {
+    return new RootStateInfo(machine, parent);
+  }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// StateInfo for substates (including Top ;-)
+// Has methods to create state specific objects.
+template<class S>
+class SubStateInfo : public StateInfo {
+ public:
+  typedef typename S::Data Data;
+
+  SubStateInfo(MachineBase & machine, StateInfo * parent)
+    : StateInfo(machine, parent) {
+    assert(parent);
+    this->instance_ = new S(*this);
+  }
+  ~SubStateInfo() {
+    if (this->data_)
+      delete_data();
+  }
+  virtual const char * name() const { return S::state_name(); }
+  virtual Key key() {
+    return S::key();
+  }
+  // 'Virtual constructor' needed for cloning.
+  virtual StateInfo * create(MachineBase & machine, StateInfo * parent) {
+    return new SubStateInfo<S>(machine, parent);
+  }
+  virtual void clone_data(void * data) {
+    assert(!data_);
+    assert(!data_place);
+    // Needs copy constructor in ALL data types.
+    data_ = new Data(*static_cast<Data *>(data));
+  }
+  virtual void create_data() {
+    this->data_ = new Data();
+  }
+  virtual void delete_data() {
+    delete static_cast<Data *>(this->data_);
+    data_ = 0;
+  }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Definitions for queuable event types
+
+// Generic interface for event objects (available only to MachineBase)
+class EventBase {
+ public:
+  virtual ~EventBase() {}
+  virtual void dispatch(StateInfo &) = 0;
+};
+
+// Interface for event objects (bound to a top state)
+template<class TOP>
+class EventParamBase : protected EventBase {
+  friend class Machine<TOP>;
+  friend class TopState<TOP>;
+};
+
+// Event with four parameters
+template<class TOP, class ROOT, class P1, class P2, class P3, class P4>
+class EventWith4Params : public EventParamBase<TOP> {
+  typedef ROOT (TOP::*Signature)(P1, P2, P3, P4);
+
+ public:
+  EventWith4Params(Signature handler, P1 p1, P2 p2, P3 p3, P4 p4)
+    : handler_(handler), param1_(p1), param2_(p2),
+    param3_(p3) , param4_(p4) {
+    assert(handler);
+  }
+
+ protected:
+  void dispatch(StateInfo & info) {
+    TOP & state = static_cast<TOP &>(info.instance());
+    (state.*handler_)(param1_, param2_, param3_, param4_);
+  }
+
+  Signature handler_;
+  P1 param1_;
+  P2 param2_;
+  P3 param3_;
+  P4 param4_;
+};
+
+// Event with three parameters
+template<class TOP, class ROOT, class P1, class P2, class P3>
+class EventWith3Params : public EventParamBase<TOP> {
+  typedef ROOT (TOP::*Signature)(P1, P2, P3);
+
+ public:
+  EventWith3Params(Signature handler, P1 p1, P2 p2, P3 p3)
+    : handler_(handler), param1_(p1), param2_(p2), param3_(p3) {
+    assert(handler);
+  }
+
+ protected:
+  void dispatch(StateInfo & info) {
+    TOP & state = static_cast<TOP &>(info.instance());
+    (state.*handler_)(param1_, param2_, param3_);
+  }
+
+  Signature handler_;
+  P1 param1_;
+  P2 param2_;
+  P3 param3_;
+};
+
+// Event with two parameters
+template<class TOP, class ROOT, class P1, class P2>
+class EventWith2Params : public EventParamBase<TOP> {
+  typedef ROOT (TOP::*Signature)(P1, P2);
+
+ public:
+  EventWith2Params(ROOT (TOP::*handler)(P1, P2), P1 p1, P2 p2)
+    : handler_(handler), param1_(p1), param2_(p2) {
+    assert(handler);
+  }
+
+ protected:
+  void dispatch(StateInfo & info) {
+    TOP & state = static_cast<TOP &>(info.instance());
+    (state.*handler_)(param1_, param2_);
+  }
+
+  Signature handler_;
+  P1 param1_;
+  P2 param2_;
+};
+
+// Event with one parameter
+template<class TOP, class ROOT, class P1>
+class EventWith1Params : public EventParamBase<TOP> {
+  typedef ROOT (TOP::*Signature)(P1);
+
+ public:
+  EventWith1Params(ROOT (TOP::*handler)(P1), P1 p1)
+    : handler_(handler), param1_(p1) {
+    assert(handler);
+  }
+
+ protected:
+  void dispatch(StateInfo & info) {
+    TOP & state = static_cast<TOP &>(info.instance());
+    (state.*handler_)(param1_);
+  }
+
+  Signature handler_;
+  P1 param1_;
+};
+
+// Event with no parameters
+template<class TOP, class ROOT>
+class EventWithoutParams : public EventParamBase<TOP> {
+  typedef ROOT (TOP::*Signature)();
+
+ public:
+  EventWithoutParams(ROOT (TOP::*handler)())
+    : handler_(handler) {
+    assert(handler);
+  }
+
+ protected:
+  void dispatch(StateInfo & info) {
+    TOP & state = static_cast<TOP &>(info.instance());
+    (state.*handler_)();
+  }
+
+  Signature handler_;
+};
+
+// Event creating functions using type inference
+template<class TOP, class ROOT, class P1, class P2, class P3, class P4>
+inline EventParamBase<TOP> * Event(
+    ROOT (TOP::*handler)(P1, P2, P3, P4), P1 p1, P2 p2, P3 p3, P4 p4) {
+  return new EventWith4Params<TOP, ROOT, P1, P2, P3, P4>(
+      handler, p1, p2, p3, p4);
+}
+
+template<class TOP, class ROOT, class P1, class P2, class P3>
+inline EventParamBase<TOP> * Event(ROOT(TOP::*handler)(
+      P1, P2, P3), P1 p1, P2 p2, P3 p3) {
+  return new EventWith3Params<TOP, ROOT, P1, P2, P3>(handler, p1, p2, p3);
+}
+
+template<class TOP, class ROOT, class P1, class P2>
+inline EventParamBase<TOP> * Event(ROOT (TOP::*handler)(P1, P2), P1 p1, P2 p2) {
+  return new EventWith2Params<TOP, ROOT, P1, P2>(handler, p1, p2);
+}
+
+template<class TOP, class ROOT, class P1>
+inline EventParamBase<TOP> * Event(ROOT (TOP::*handler)(P1), P1 p1) {
+  return new EventWith1Params<TOP, ROOT, P1>(handler, p1);
+}
+
+template<class TOP, class ROOT>
+inline EventParamBase<TOP> * Event(ROOT (TOP::*handler)()) {
+  return new EventWithoutParams<TOP, ROOT>(handler);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Base class for Machine objects.
+class EXPORT_DLL MachineBase {
+ public:
+  // Transition to new state (with optional preinitialized data).
+  void set_state(StateInfo & info, bool history, void * data);
+  // Transition to new state specified by state alias.
+  void set_state(const StateAlias & state, bool history);
+  // Prepare transition to new state (performed on call to "perform_pending").
+  // There can be only one state transition pending (asserts otherwise)!
+  // "data" is an optional preinitialized state data for the new state.
+  void set_pending_state(StateInfo & info, bool history, void * data) {
+    assert((!pending_state_ || pending_state_ == &info) &&
+        "There is already a state transition pending!");
+
+    pending_state_ = &info;
+    pending_data_ = data;
+    pending_history_ = history;
+  }
+  void set_pending_event(EventBase * event) {
+    assert(event);
+    assert(!pending_event_ && "There is already an event pending!");
+
+    pending_event_ = event;
+  }
+  void add_deferred_event(EventBase * event, const std::string& name);
+  // Performs pending state transition.
+  void perform_pending();
+  // Performs pending state transition.
+  void perform_pending_event();
+  // Performs deferred events.
+  void perform_deferred_events();
+  // Get StateInfo object for key.
+  StateInfo * & get_info(Key name) {
+    return states_[name];
+  }
+  bool is_current(StateInfo & info) {
+    return current_state_->is_child(info);
+  }
+  bool is_current_direct(StateInfo & info) const {
+    return current_state_ == &info;
+  }
+
+ protected:
+  MachineBase();
+  ~MachineBase();
+  // Starts the machine. Will make it go into top state.
+  // Optional parameter "data" is a preinitialized state data for the top
+  // state.
+  void start(StateInfo & info, void * data);
+  // Shuts machine down. Will exit any states and free all allocated
+  // resources.
+  void shutdown();
+  // Allocate space for pointers to StateInfo objects.
+  void allocate(unsigned int count);
+  // Free all StateInfo objects.
+  void free(unsigned int count);
+  // Create a copy of another machines StateInfo objects (includes dataes).
+  void copy(StateInfo ** other, unsigned int count);
+  // Create a copy of another machines StateInfo object.
+  StateInfo * create_clone(Key key, StateInfo * original);
+
+ protected:
+  typedef std::map<std::string, EventBase *> EventQueue;
+  typedef std::vector<std::string> EventNames;
+
+  // C++ needs something like package visibility
+  // for set_pending_state
+  friend class StateInfo;
+  friend class StateBase;
+
+  // Current state of Machine object.
+  StateInfo * current_state_;
+  // Information about pending state transition.
+  StateInfo * pending_state_;
+  void * pending_data_;
+  bool pending_history_;
+  EventBase * pending_event_;
+  EventQueue deferred_events_;
+  EventNames deferred_names_;
+  // Array of StateInfo objects.
+  StateInfo ** states_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Implementation for TopState
+template<class T>
+inline void TopState<T>::dispatch(EventParamBase<TOP> * event) {
+  assert(event);
+  state_info_.machine().set_pending_event(event);
+}
+
+template<class T>
+inline void TopState<T>::defer(EventParamBase<TOP> * event,
+    const std::string& name) {
+  assert(event);
+  state_info_.machine().add_deferred_event(event, name);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Implementation for Link
+template<class C, class P>
+inline Link<C, P>::Link(StateInfo & info)
+: P(P::get_info(info.machine()))
+  // Can't initialize state_info_ with get_info,
+  // because this would result in an endless loop (at least for first call)
+  , state_info_(info) {}
+
+// Create StateInfo object of state.
+template<class C, class P>
+inline StateInfo & Link<C, P>::get_info(MachineBase & machine) {
+  // Look first in machine for existing StateInfo.
+  StateInfo * & info = machine.get_info(key());
+  if (!info) {
+    // Will create parent StateInfo object if not already created.
+    info = new SubStateInfo<C>(machine, &P::get_info(machine));
+  }
+  return *info;
+}
+
+// This method keeps 'state_info_' attribute private.
+template<class C, class P>
+inline void * Link<C, P>::local_data() {
+  return state_info_.data();
+}
+
+// Default behaviour: free data on exit.
+template<class C, class P>
+inline void Link<C, P>::delete_data(StateInfo & info) {
+  info.delete_data();
+}
+
+
+// Objects of this class represent states in user code.  They are used to
+// create aliases to be used as parameters to the set_state method to
+// initiate transitions to the specified state.
+// If the object is created with a data instance for the state, that data
+// instance is used to initialize the state on transition:
+//
+// Example:
+//              StateAlias a = State<StateA>(new StateA::Data(42));
+//              ...
+//              set_state(a);
+template<class S>
+class State : public StateAlias {
+ public:
+  // Can be given a data to be used when transitioning to template
+  // parameter state.
+  explicit State(typename S::Data * data = 0)
+    : StateAlias(&the_character_, data) {}
+
+ private:
+  static StateInfo & get_info(MachineBase & machine) {
+    return S::get_info(machine);
+  }
+  static void destroy(void * data) {
+    delete static_cast<typename S::Data *>(data);
+  }
+  static void * clone(void * data) {
+    typedef typename S::Data Data;
+    return new Data(* static_cast<Data *>(data));
+  }
+
+ private:
+  static StateCharacter the_character_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Snapshot of a machine object.
+// Saves the state of a machine object at a specific point in time to be
+// restored later (can be used to achieve something like backtracking).
+// Includes dataes of current state and persistent dataes.
+// Assign a snapshot to a machine (operator=) to restore state.
+// Note that no exit/entry actions of the overwritten machine state are
+// performed! Data destructors however are executed!
+template<class TOP>
+class Snapshot : public MachineBase {
+ public:
+  Snapshot(const Machine<TOP> & machine);  // NOLINT
+  ~Snapshot() {
+    free(Machine<TOP>::the_state_count_);
+  }
+
+ private:
+  friend class Machine<TOP>;
+
+  Snapshot(const Snapshot<TOP> & other);
+  Snapshot & operator=(const Snapshot<TOP> & other);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// A Machine object maintains a current state.
+// The state can be any substate of template parameter TOP.
+// TOP is the Machine's top most and inital state. TOP must be defined by
+// the macro TOPSTATE. Event processing is done by calling methods (event
+// handlers) on the current state.
+// This is realized by defining an arrow ("->") operator on Machine,
+// forwarding to the interface of TOP.
+// Every possible event handler to be called must therefore appear in the
+// interface of TOP. Events are dispatched by using this operator on a
+// Machine object (e.g. "machine->event()").
+template<class TOP>
+class Machine : public MachineBase {
+ public:
+  //////////////////////////////////////////////////////////////////////////////
+  // This class performs an action in its destructor after an event
+  // handler has finished. Comparable to an After Advice in AOP.
+  struct AfterAdvice {
+    AfterAdvice(Machine<TOP> & m) : machine_(m) {}  // NOLINT
+
+    // Event handler has finished execution. Execute pending transitions now.
+    ~AfterAdvice() { machine_.perform_pending(); }
+
+    // this arrow operator finally dispatches to TOP interface.
+    TOP * operator->() {
+      return static_cast<TOP *>(& (machine_.current_state_->instance()) );
+    }
+
+   private:
+     Machine<TOP> & machine_;
+  };
+  friend struct AfterAdvice;
+
+  // Constructor takes an optional preinitialized Data parameter for its
+  // initial (top) state.
+  Machine(typename TOP::Data * data = 0) {  // NOLINT
+    // Compile time check: TOP must directly derive from TopState<TOP>
+    TopState<TOP> * p = 0;
+    typename TOP::SUPER * p2 = 0;
+    p2 = p;
+    allocate(the_state_count_);
+    start(TOP::get_info(*this), data);
+  }
+  // Initialize with a state alias object to have machine go to a state
+  // other than TOP on startup.
+  Machine(const StateAlias & state) {  // NOLINT
+    // Compile time check: TOP must directly derive from TopState<TOP>
+    TopState<TOP> * p = 0;
+    typename TOP::SUPER * p2 = 0;
+    p2 = p;
+    allocate(the_state_count_);
+    start(state.get_info(*this), state.take_data());
+  }
+  // Create machine from a snapshot.
+  Machine(const Snapshot<TOP> & snapshot) {  // NOLINT
+    allocate(the_state_count_);
+    copy(snapshot.states_, the_state_count_);
+  }
+  // Overwrite current machine state by snapshot.
+  Machine<TOP> & operator=(const Snapshot<TOP> & snapshot) {
+    assert(!pending_state_);
+    assert(!pending_event_);
+
+    current_state_->shutdown();
+    free(the_state_count_);
+    copy(snapshot.states_, the_state_count_);
+    // Go to Root state first
+    current_state_ = get_info(0);
+    // Then set previous current state
+    StateInfo * current = get_info(snapshot.current_state_->key());
+    current->restore(*current);
+    perform_pending();
+    return *this;
+  }
+  ~Machine() {
+    current_state_->shutdown();
+    free(the_state_count_);
+  }
+  // Don't return pointer to interface right now: we need to know when the
+  // event handler has finished; return an AfterAdvice object instead:
+  // it allows us to perform actions after access.
+  AfterAdvice operator->() {
+    assert(current_state_);
+    assert(!pending_state_);
+
+    // We need to know when the event handler has finished.
+    return AfterAdvice(*this);
+  }
+  // Dispatch an event object to machine.
+  void dispatch(EventParamBase<TOP> * event, bool destroy = true) {
+    assert(event);
+
+    event->dispatch(*current_state_);
+    if (destroy) delete event;
+    perform_pending();
+  }
+  // Allow (const) access to top state's data (for state data extraction).
+  const typename TOP::Data & data() const {
+    assert(current_state_);
+    return static_cast<TOP &>(current_state_->instance()).TOP::data();
+  }
+  // Clear history of state and children.
+  void clear_history_deep(StateInfo & state) {
+    for (unsigned int i = 0; i < the_state_count_; ++i) {
+      StateInfo * s = states_[i];
+      if (s && s->is_child(state))
+        s->set_history(0);
+    }
+  }
+
+  // Next free identifier for StateInfo objects.
+  static Key the_state_count_;
+
+ private:
+  Machine(const Machine<TOP> & other);
+  Machine<TOP> & operator=(const Machine<TOP> & other);
+
+  friend class Snapshot<TOP>;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Implementation for Snapshot
+template<class TOP>
+Snapshot<TOP>::Snapshot(const Machine<TOP> & machine) {
+  assert(!machine.pending_state_);
+  assert(!machine.pending_event_);
+  assert(machine.current_state_);
+
+  allocate(Machine<TOP>::the_state_count_);
+  copy(machine.states_, Machine<TOP>::the_state_count_);
+  current_state_ = get_info(machine.current_state_->key());
+}
+
+// Root is always there and has key 0, so start from 1
+template<class TOP> Key Machine<TOP>::the_state_count_ = 1;
+
+// DIY virtual function table of class 'State'.
+template<class S> StateCharacter State<S>::the_character_ = {
+  State<S>::get_info,
+  State<S>::destroy,
+  State<S>::clone
+};
+
+}  // namespace sc
+}  // namespace hrtm
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+#endif  // HRTM_STATECHART_H_

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/utils.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/utils.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/utils.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,39 @@
+#ifndef HRTM_UTILS_H
+#define HRTM_UTILS_H
+#include <iostream>
+using namespace std;
+
+namespace hrtm
+{
+  ostream& operator<<(ostream& os, const SDOPackage::NameValue& nv) {
+  os << "name:" << nv.name << endl;
+  const char* tmp(NULL);
+  os << "value:";
+  if (nv.value >>= tmp) {
+    os << tmp << endl;
+  } else {
+    os << "<<<NO PRINTABLE>>>" << endl;
+  }
+  return os;
+}
+
+ostream& operator<<(ostream& os, const SDOPackage::NVList& nvlist) {
+  CORBA::ULong len(nvlist.length());
+  for (CORBA::ULong i(0); i < len; i++) {
+    os << nvlist[i];
+  }
+  return os;
+}
+
+ostream& operator<<(ostream& os, const SDOPackage::ConfigurationSet& cs) {
+  os << "---[BEGIN ConfigurationSet]---" << endl;
+  os << "id:" << cs.id << endl;
+  os << "description:" << cs.description << endl;
+  os << "configuration_data:" << endl;
+  os << cs.configuration_data << endl;
+  os << "---[END   ConfigurationSet]---" << endl;
+  return os;
+}
+};
+
+#endif // HRTM_UTILS_H


Property changes on: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/utils.h
___________________________________________________________________
Added: svn:executable
   + *

Added: branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/version.h
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/version.h	                        (rev 0)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/hrtm/version.h	2016-10-07 01:32:30 UTC (rev 2763)
@@ -0,0 +1,6 @@
+// This header file is automatically generated.
+// Do not edit this file.
+
+const char* openrtm_name    = "OpenRTM-aist-1.1.2";
+const char* openrtm_version = "1.1.2";
+const char* corba_name      = "omniORB";

Modified: branches/FSM4RTC/OpenRTM-aist/src/lib/rtm/Makefile.am
===================================================================
--- branches/FSM4RTC/OpenRTM-aist/src/lib/rtm/Makefile.am	2016-10-06 06:25:12 UTC (rev 2762)
+++ branches/FSM4RTC/OpenRTM-aist/src/lib/rtm/Makefile.am	2016-10-07 01:32:30 UTC (rev 2763)
@@ -41,13 +41,13 @@
 #	PortProfileHelper.cpp
 #	ObjectManager.cpp
 
-UTIL_SRC =                \
+UTIL_SRC =            \
 	CORBA_IORUtil.cpp \
 	NVUtil.cpp        \
 	RTCUtil.cpp       \
 	DefaultPeriodicTask.cpp
 
-MGR_SRC =                            \
+MGR_SRC =                        \
 	FactoryInit.cpp              \
 	CorbaNaming.cpp              \
 	Factory.cpp                  \
@@ -62,7 +62,7 @@
 	LocalServiceAdmin.cpp        \
 	ManagerActionListener.cpp
 
-COMP_SRC =                           \
+COMP_SRC =                       \
 	DataFlowComponentBase.cpp    \
 	ExecutionContextBase.cpp     \
 	ExecutionContextProfile.cpp  \
@@ -81,7 +81,7 @@
 	SdoOrganization.cpp          \
 	PeriodicECSharedComposite.cpp
 
-PORT_SRC =                           \
+PORT_SRC =                       \
 	InPortConnector.cpp          \
 	OutPortConnector.cpp         \
 	OutPortPullConnector.cpp     \



More information about the openrtm-commit mailing list