Program Listing for File population_dynamics.hpp

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

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <algorithm>
#include <queue>
#include <utility>
#include <vector>

#include "rcppsw/ds/poisson_queue.hpp"
#include "rcppsw/er/client.hpp"
#include "rcppsw/math/rng.hpp"
#include "rcppsw/rcppsw.hpp"
#include "rcppsw/types/timestep.hpp"
#include "rcppsw/types/type_uuid.hpp"

#include "cosm/tv/config/population_dynamics_config.hpp"
#include "cosm/tv/metrics/population_dynamics_metrics.hpp"

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

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
class population_dynamics : public rer::client<population_dynamics>,
                            public metrics::population_dynamics_metrics {
 public:
  struct op_result {
    rtypes::type_uuid id;
    size_t total_pop;
    size_t active_pop;
  };

  population_dynamics(const config::population_dynamics_config* config,
                      size_t total_pop,
                      size_t active_pop,
                      rmath::rng* rng);
  ~population_dynamics(void) override = default;

  population_dynamics(const population_dynamics&) = delete;
  const population_dynamics& operator=(const population_dynamics&) = delete;

  void update(const rtypes::timestep& t);

  /* population dynamics metrics overrides */
  queue_status birth_queue_status(void) const override RCPPSW_PURE;
  queue_status death_queue_status(void) const override RCPPSW_PURE;
  queue_status repair_queue_status(void) const override RCPPSW_PURE;
  size_t swarm_max_population(void) const override { return mc_config.max_size; }
  size_t swarm_total_population(void) const override { return m_total_pop; }
  size_t swarm_active_population(void) const override { return m_active_pop; }
  void reset_metrics(void) override final {
    m_birth.reset_metrics();
    m_death.reset_metrics();
    m_repair.reset_metrics();
  }

 protected:
  bool already_killed(const rtypes::type_uuid& id) const {
    return m_death.contains(id);
  }

  bool currently_repairing(const rtypes::type_uuid& id) const {
    return m_repair.contains(id);
  }

  virtual op_result robot_kill(void) = 0;

  virtual op_result robot_add(int max_pop, const rtypes::type_uuid& id) = 0;

  virtual op_result robot_malfunction(void) = 0;

  virtual op_result robot_repair(const rtypes::type_uuid& id) = 0;

 private:
  void death_dynamics(const rtypes::timestep& t);
  void birth_dynamics(const rtypes::timestep& t);
  void malfunction_dynamics(const rtypes::timestep& t);
  void repair_dynamics(const rtypes::timestep& t);

  /* clang-format off */
  const config::population_dynamics_config mc_config;

  size_t                                   m_total_pop;
  size_t                                   m_active_pop;
  rtypes::timestep                         m_timestep{0};
  rmath::rng*                              m_rng;

  rds::poisson_queue<rtypes::type_uuid>    m_birth;
  rds::poisson_queue<rtypes::type_uuid>    m_death;
  rds::poisson_queue<rtypes::type_uuid>    m_repair;
  /* clang-format on */
};

} /* namespace cosm::tv */