Program Listing for File base_actuation_subsystem.hpp

Return to documentation for file (cosm/hal/subsystem/base_actuation_subsystem.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <typeindex>
#include <unordered_map>
#include <variant>
#include <utility>

#include "rcppsw/mpl/typelist.hpp"
#include "rcppsw/types/timestep.hpp"

#include "cosm/hal/subsystem/base_subsystem.hpp"
#include "cosm/hal/subsystem/actuator_map.hpp"

/*******************************************************************************
 * Namespaces
 ******************************************************************************/
namespace cosm::hal::subsystem {

/*******************************************************************************
 * Macros
 ******************************************************************************/
#define COSM_HAL_ACTUATOR_ACCESSOR(type, name, ...)           \
  COSM_HAL_SAA_ACCESSOR(actuator, type, name, __VA_ARGS__)

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
template <typename ...TActuatorTypes>
class base_actuation_subsystem : private chsubsystem::base_subsystem {
 public:
  using variant_type = actuator_variant<TActuatorTypes...>;
  using actuator_map = actuator_variant_map<TActuatorTypes...>;

  template <typename TActuator>
  static typename actuator_map::value_type map_entry_create(
      TActuator&& actuator) {
    return { typeid(TActuator), variant_type(std::move(actuator)) };
  }

  explicit base_actuation_subsystem(actuator_map&& actuators)
      : m_actuators(std::move(actuators)) {}

  virtual ~base_actuation_subsystem(void) = default;

  void reset(void) { base_subsystem::reset(m_actuators); }

  void disable(void) { base_subsystem::disable(m_actuators); }

  template <typename TActuator>
  bool replace(const TActuator& actuator) {
    if (m_actuators.end() != m_actuators.find(typeid(actuator))) {
      m_actuators.erase(m_actuators.find(typeid(actuator)));
      return m_actuators.insert(map_entry_create(actuator)).second;
    }
    return false;
  }

  template <typename T>
  const T* actuator(void) const {
    return &std::get<T>(m_actuators.find(typeid(T))->second);
  }

  template <typename T>
  T* actuator(void) {
    return &std::get<T>(m_actuators.find(typeid(T))->second);
  }

 private:
  /* clang-format off */
  actuator_map m_actuators;
  /* clang-format off */
};

} /* namespace cosm::hal::subsystem */