Program Listing for File free_block_drop.hpp

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

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <memory>

#include "rcppsw/er/client.hpp"
#include "rcppsw/math/vector2.hpp"

#include "cosm/ds/operations/cell2D_op.hpp"
#include "cosm/arena/locking.hpp"
#include "cosm/repr/block_variant.hpp"

/*******************************************************************************
 * Namespaces
 ******************************************************************************/
namespace cosm::arena {
class caching_arena_map;
class base_arena_map;
} /* namespace cosm::arena */

namespace cosm::repr {
class sim_block3D;
} /* namespace cosm::repr */

namespace cosm::arena::operations {
namespace detail {

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
class free_block_drop : public rer::client<free_block_drop>,
                        public cdops::cell2D_op {
 private:
  struct visit_typelist_impl {
    using inherited = cell2D_op::visit_typelist;
    using others = rmpl::typelist<base_arena_map,
                                  caching_arena_map,
                                  crepr::sim_block3D>;
    using value = boost::mpl::joint_view<inherited::type, others::type>;
  };

 public:
  using visit_typelist = typename visit_typelist_impl::value;

  static free_block_drop for_block(const rmath::vector2z& coord,
                                   const rtypes::discretize_ratio& resolution);

  ~free_block_drop(void) override = default;

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

  void visit(base_arena_map& map);
  void visit(caching_arena_map& map);

  void visit(cds::cell2D& cell);

  void visit(crepr::sim_block3D& block);

 protected:
  free_block_drop(crepr::sim_block3D* block,
                  const rmath::vector2z& coord,
                  const rtypes::discretize_ratio& resolution,
                  const locking& locking);

 private:
  void visit(fsm::cell2D_fsm& fsm);

  template <typename TMap>
  void execute_free_drop(TMap& map, cds::cell2D& cell);

  /* clang-format off */
  const rtypes::discretize_ratio mc_resolution;
  const locking                  mc_locking;

  crepr::sim_block3D*           m_block;
  /* clang-format on */
};

using free_block_drop_visitor_impl =
    rpvisitor::precise_visitor<free_block_drop,
                               free_block_drop::visit_typelist>;

} /* namespace detail */

class free_block_drop_visitor : public detail::free_block_drop_visitor_impl {
 public:
  using detail::free_block_drop_visitor_impl::free_block_drop_visitor_impl;
};


} /* namespace cosm::arena::operations */