Program Listing for File base_arena_map.hpp

Return to documentation for file (cosm/arena/base_arena_map.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <list>
#include <map>
#include <memory>
#include <shared_mutex>
#include <string>
#include <vector>

#include "rcppsw/er/client.hpp"
#include "rcppsw/multithread/lockable.hpp"
#include "rcppsw/patterns/decorator/decorator.hpp"
#include "rcppsw/types/type_uuid.hpp"

#include "cosm/arena/ds/arena_grid.hpp"
#include "cosm/arena/ds/nest_vector.hpp"
#include "cosm/arena/locking.hpp"
#include "cosm/arena/update_status.hpp"
#include "cosm/ds/block3D_vector.hpp"
#include "cosm/ds/entity_vector.hpp"
#include "cosm/foraging/block_dist/base_distributor.hpp"
#include "cosm/foraging/block_dist/redist_governor.hpp"
#include "cosm/foraging/block_motion_handler.hpp"
#include "cosm/spatial/common/conflict_checker.hpp"

/*******************************************************************************
 * Namespaces
 ******************************************************************************/
namespace cosm::arena::config {
struct arena_map_config;
}
namespace cosm::arena::ds {
class loctree;
} /* namespace cosm::arena::ds */

namespace cosm::pal::argos {
class swarm_manager_adaptor;
}
namespace cosm::ds {
class cell2D;
} /* namespace cosm::ds */
namespace cosm::repr {
class nest;
namespace config {
struct nests_config;
} /* namespace config */
} /* namespace cosm::repr */

namespace cosm::foraging::block_dist {
class dispatcher;
}

namespace cosm::arena {

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
class base_arena_map : public rer::client<base_arena_map>,
                       public rpdecorator::decorator<ds::arena_grid>,
                       public rmultithread::lockable {
 public:
  using grid_view = rds::base_grid2D<cds::cell2D>::grid_view;
  using const_grid_view = rds::base_grid2D<cds::cell2D>::const_grid_view;

  base_arena_map(const caconfig::arena_map_config* config, rmath::rng* rng);
  ~base_arena_map(void) override;

  /* Not move/copy constructable/assignable by default */
  base_arena_map(const base_arena_map&) = delete;
  const base_arena_map& operator=(const base_arena_map&) = delete;
  base_arena_map(base_arena_map&&) = delete;
  base_arena_map& operator=(base_arena_map&&) = delete;

  template <size_t Index>
  typename ds::arena_grid::layer_value_type<Index>::value_type&
  access(const rmath::vector2z& d) {
    return decoratee().template access<Index>(d);
  }
  template <size_t Index>
  const typename ds::arena_grid::layer_value_type<Index>::value_type&
  access(const rmath::vector2z& d) const {
    return decoratee().template access<Index>(d);
  }
  template <size_t Index>
  typename ds::arena_grid::layer_value_type<Index>::value_type& access(size_t i,
                                                                       size_t j) {
    return decoratee().template access<Index>(i, j);
  }
  template <size_t Index>
  const typename ds::arena_grid::layer_value_type<Index>::value_type&
  access(size_t i, size_t j) const {
    return decoratee().template access<Index>(i, j);
  }

  RCPPSW_DECORATE_DECLDEF(xdsize, const);
  RCPPSW_DECORATE_DECLDEF(ydsize, const);
  RCPPSW_DECORATE_DECLDEF(xrsize, const);
  RCPPSW_DECORATE_DECLDEF(yrsize, const);
  RCPPSW_DECORATE_DECLDEF(rdims2D, const);
  RCPPSW_DECORATE_DECLDEF(ddims2D, const);

  rtypes::discretize_ratio grid_resolution(void) const {
    return decoratee().resolution();
  }

  virtual rtypes::type_uuid robot_on_block(const rmath::vector2d& pos,
                                           const rtypes::type_uuid& ent_id) const;

  rtypes::type_uuid robot_in_nest(const rmath::vector2d& pos) const RCPPSW_PURE;

  virtual bool placement_conflict(const crepr::sim_block3D* block,
                                  const rmath::vector2d& loc) const;

  update_status pre_step_update(const rtypes::timestep& t);

  void post_step_update(const rtypes::timestep& t,
                        size_t blocks_transported,
                        bool convergence_status);

  virtual cds::block3D_vectorno free_blocks(bool oos_ok) const;

  virtual void bloctree_update(const crepr::sim_block3D* block,
                               const locking& locking);

  cds::block3D_vectorno& blocks(void) { return m_blocksno; }
  const cds::block3D_vectorno& blocks(void) const { return m_blocksno; }

  void distribute_single_block(crepr::sim_block3D* block, const locking& locking);

  const rmath::vector3d& block_bb(void) const { return m_block_bb; }

  ds::nest_vectorro nests(void) const;

  const crepr::nest* nest(const rtypes::type_uuid& id) const RCPPSW_PURE;

  const cfbd::base_distributor* block_distributor(void) const RCPPSW_PURE;
  cfbd::base_distributor* block_distributor(void) RCPPSW_PURE;
  const rmath::rangez& distributable_cellsx(void) const RCPPSW_PURE;
  const rmath::rangez& distributable_cellsy(void) const RCPPSW_PURE;

  const cads::loctree* bloctree(void) const { return m_bloctree.get(); }
  const cads::loctree* nloctree(void) const { return m_nloctree.get(); }

  virtual bool initialize(cpargos::swarm_manager_adaptor* sm,
                          const crepr::config::nests_config* nests);

  std::shared_mutex* grid_mtx(void) { return decoratee().mtx(); }

  std::shared_mutex* block_mtx(void) { return &m_block_mtx; }
  std::shared_mutex* block_mtx(void) const { return &m_block_mtx; }

  virtual void ordered_lock(const locking& locking);
  virtual void ordered_unlock(const locking& locking);

 protected:
  virtual void pre_block_dist_lock(const locking& locking);

  virtual void post_block_dist_unlock(const locking& locking);

  virtual bool bloctree_verify(void) const;

  ds::loctree* bloctree(void) { return m_bloctree.get(); }

  virtual cds::const_spatial_entity_vector
  initial_dist_precalc(const crepr::sim_block3D*) const {
    return {};
  };
  bool initialize_shared(cpargos::swarm_manager_adaptor* sm,
                         const crepr::config::nests_config* nests);

  bool distribute_all_blocks(void);
  cfbd::dispatcher* block_dispatcher(void) const {
    return m_block_dispatcher.get();
  }
  rmath::rng* rng(void) const { return m_rng; }

 private:
  using nest_map_type = std::map<rtypes::type_uuid, crepr::nest>;
  struct pending_dist_type {
    crepr::sim_block3D* block;
    size_t fail_count;
  };

  bool initialize_private(void);

  void initialize_nests(const crepr::config::nests_config* nests,
                        cpargos::swarm_manager_adaptor* sm,
                        const rtypes::discretize_ratio& resolution);

  /* clang-format off */
  mutable std::shared_mutex              m_block_mtx{};
  std::shared_mutex                      m_bloctree_mtx{};

  rmath::rng*                            m_rng;
  rmath::vector3d                        m_block_bb{};
  cds::block3D_vectoro                   m_blockso;
  cds::block3D_vectorno                  m_blocksno{};

  std::list<pending_dist_type>           m_pending_dists{};
  std::unique_ptr<cfbd::dispatcher>      m_block_dispatcher;
  cfbd::redist_governor                  m_redist_governor;
  cforaging::block_motion_handler        m_bm_handler;
  mutable std::unique_ptr<nest_map_type> m_nests;
  std::unique_ptr<cads::loctree>         m_bloctree;
  std::unique_ptr<cads::loctree>         m_nloctree;
  /* clang-format on */

 public:
  RCPPSW_PTRREF_DECLDEF_CONST(block_motion_handler, m_bm_handler);
  RCPPSW_PTRREF_DECLDEF(redist_governor, m_redist_governor);
};

} /* namespace cosm::arena */