Program Listing for File StateMachine.hpp

Return to documentation for file (src/mimir/StateMachine.hpp)

#pragma once

#include <future>
#include <memory>

#include <boost/log/trivial.hpp>
#include <boost/mpl/list.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>
#include <boost/statechart/deferral.hpp>

#include "yaml-cpp/yaml.h"
#include "mimir/StateMachineFwd.hpp"

namespace mimir { namespace control {
    class CommandResponder;
    class StateNotifier;
  } }
namespace mimir { class IAlgorithm; }
namespace mpl = boost::mpl;

namespace mimir
{

  struct StateMachine : bsc::asynchronous_state_machine
  <
    StateMachine,
    Standby,
    bsc::fifo_scheduler<>,
    std::allocator<void>,
    bsc::exception_translator<>
    >
  {
    StateMachine(my_context ctx, const YAML::Node& config, std::atomic<bool>& notify_others);
    ~StateMachine();
    class DdsTriad;
  public:
    DdsTriad * Dds();
    control::StateNotifier * Notifier(){ return m_notifier.get(); }
    const YAML::Node & Config(){ return m_config; }
  private:
    //virtual void initiate_impl();
    std::unique_ptr<DdsTriad> m_dds;
    std::unique_ptr<control::CommandResponder> m_responder;
    std::unique_ptr<control::StateNotifier> m_notifier;
    std::atomic<bool>& m_notify_others;
    const YAML::Node m_config;
  };

  struct Standby : bsc::state< Standby, StateMachine >
  {
    typedef mpl::list
    <
      bsc::transition< EvStart, Running >,
      bsc::transition< EvKill, ShutDown >,
      bsc::custom_reaction< EvTimeout >
      > reactions;

    Standby(my_context ctx);
    ~Standby();
    bsc::result react(const EvTimeout &);
  };

  struct ShutDown : bsc::state< ShutDown, StateMachine >
  {
    typedef mpl::list
    <
      bsc::custom_reaction< EvKill >
      > reactions;

    ShutDown(my_context ctx);
    ~ShutDown();
    bsc::result react(const EvKill &);
  };

  struct Running : bsc::state< Running, StateMachine, Initializing >
  {
    typedef mpl::list
    <
      bsc::transition< EvStop, Standby >,
      bsc::transition< EvKill, ShutDown >,
      bsc::transition< EvError, ShutDown >,
      bsc::transition< EvInterrupt, Standby >,
      bsc::custom_reaction< bsc::exception_thrown >
      > reactions;

    Running(my_context ctx);
    ~Running();
    bsc::result react(const bsc::exception_thrown &);
    mimir::IAlgorithm* Algorithm();

  private:
    std::unique_ptr<mimir::IAlgorithm> m_algorithm;
  };

  struct Initializing : bsc::state< Initializing, Running >
  {
    typedef mpl::list
    <
      bsc::custom_reaction< EvReady >
      > reactions;

    Initializing(my_context ctx);
    ~Initializing();
    bsc::result react(const EvReady &);

  private:
    std::future<void> m_future;
    std::atomic<bool> m_canceled;
  };

  struct Evaluating : bsc::state< Evaluating, Running >
  {
    typedef mpl::list
    <
      bsc::custom_reaction< EvReady >
      > reactions;

    Evaluating(my_context ctx);
    ~Evaluating();
    bsc::result react(const EvReady &);

  private:
    std::future<void> m_future;
    std::atomic<bool> m_canceled;
  };

  struct Waiting : bsc::state< Waiting, Running >
  {
    typedef mpl::list
    <
      bsc::transition< EvTimeout, Evaluating >
      > reactions;

    Waiting(my_context ctx);
    ~Waiting();

  private:
    std::future<void> m_future;
    std::atomic<bool> m_canceled;
  };

}