Program Listing for File state_action.hpp

Return to documentation for file (rcppsw/patterns/fsm/state_action.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <cassert>
#include "rcppsw/rcppsw.hpp"
#include "rcppsw/patterns/fsm/event.hpp"
#include "rcppsw/patterns/fsm/state.hpp"

/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::patterns::fsm {

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
template <class SM, int (SM::*Func)(void)>
class state_action0 : public state {
 public:
  state_action0(void) = default;
  state_action0(const state_action0&) = default;
  ~state_action0(void) override = default;

  int invoke_state_action(base_fsm* sm,
                          RCPPSW_UNUSED event_data*) const override {
    /* Downcast the state machine and event data to the correct derived type */
    auto* derived_fsm = static_cast<SM*>(sm);
    return (derived_fsm->*Func)();
  }
};

template <class SM, class Event, int (SM::*Func)(Event*)>
class state_action1 : public state {
 public:
  state_action1(void) = default;
  ~state_action1(void) override = default;
  state_action1(const state_action1&) = default;

  int invoke_state_action(base_fsm* sm, event_data* data) const override {
    /* Downcast the state machine and event data to the correct derived type */
    auto* derived_fsm = static_cast<SM*>(sm);
    Event* derived_event = nullptr;

    /*
     * If this check fails, there is a mismatch between the STATE_DECLARE event
     * data type and the data type being sent to the state function.
     */
    if (nullptr != data) {
      derived_event = dynamic_cast<Event*>(data);
      assert(derived_event);
    }

    return (derived_fsm->*Func)(derived_event);
  }
};

} /* namespace rcppsw::patterns::fsm */