Program Listing for File temporal_penalty_handler.hpp

Return to documentation for file (cosm/tv/temporal_penalty_handler.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <list>
#include <memory>
#include <mutex>
#include <string>

#include "rcppsw/control/periodic_waveform.hpp"
#include "rcppsw/er/client.hpp"
#include "rcppsw/multithread/lockable.hpp"

#include "cosm/tv/config/temporal_penalty_config.hpp"
#include "cosm/tv/temporal_penalty.hpp"

/*******************************************************************************
 * Namespaces
 ******************************************************************************/
namespace cosm::tv {

/*******************************************************************************
 * Classes
 ******************************************************************************/

class temporal_penalty_handler : public rer::client<temporal_penalty_handler>,
                                 public rmultithread::lockable {
 public:
  using const_iterator_type =
      typename std::list<temporal_penalty>::const_iterator;

  temporal_penalty_handler(
      const ctv::config::temporal_penalty_config* const config,
      const std::string& name);

  ~temporal_penalty_handler(void) override = default;

  /* Not copy assignable/copy constructible by default */
  temporal_penalty_handler& operator=(const temporal_penalty_handler&) = delete;
  temporal_penalty_handler(const temporal_penalty_handler&) = delete;

  const std::string& name(void) const { return mc_name; }

  temporal_penalty penalty_next(void) const;

  void penalty_remove(const temporal_penalty& victim, bool lock = true);

  void penalty_abort(const controller::base_controller& controller);

  bool is_serving_penalty(const controller::base_controller& controller,
                          bool lock = true) const RCPPSW_PURE;

  bool is_penalty_satisfied(const controller::base_controller& controller,
                            const rtypes::timestep& t) const RCPPSW_PURE;

  const_iterator_type penalty_find(const controller::base_controller& controller,
                                   bool lock = true) const;

  rtypes::timestep penalty_calc(const rtypes::timestep& t) const;

 protected:
  rtypes::timestep penalty_add(const controller::base_controller* controller,
                               const rtypes::type_uuid& id,
                               const rtypes::timestep& orig_duration,
                               const rtypes::timestep& start);

 private:
  /*
   * \brief Deconflict penalties such that at most 1 robot finishes
   * serving their penalty per timestep.
   *
   * No locking is needed because this is a private function.
   *
   * \param duration The calculated penalty sans deconfliction. Passed by value
   *                 and modified, in order to make calculations simpler.
   */
  rtypes::timestep penalty_finish_uniqueify(const rtypes::timestep& start,
                                            rtypes::timestep duration) const;

  /* clang-format off */
  const bool                          mc_unique_finish;
  const std::string                   mc_name;

  std::list<temporal_penalty>         m_penalty_list{};
  mutable std::shared_mutex           m_list_mtx{};
  std::unique_ptr<rct::base_waveform> m_waveform;
  /* clang-format on */
};

} /* namespace cosm::tv */