15 #ifndef _ENTITY_COMPONENT_DENSEPOOL_H_INCLUDED_
16 #define _ENTITY_COMPONENT_DENSEPOOL_H_INCLUDED_
18 #include <boost/assert.hpp>
19 #include <boost/bind/bind.hpp>
20 #include <boost/bind/placeholders.hpp>
21 #include <boost/ref.hpp>
22 #include <boost/iterator/iterator_facade.hpp>
23 #include <boost/signals2.hpp>
24 #include <boost/signals2/connection.hpp>
32 #include "entity/config.hpp"
39 struct forward_traversal_tag;
45 namespace entity {
namespace component
47 template<
typename ComponentPool>
49 template<
typename ComponentPool>
63 : boost::iterator_facade<
66 , boost::forward_traversal_tag
79 friend class boost::iterator_core_access;
82 typedef typename std::vector<char>::iterator parent_iterator;
86 , entity_index_(start)
89 auto available_iterator = parent_->available_.begin() + start;
90 while(entity_index_ < parent_->available_.size() && *available_iterator)
99 auto available_iterator = parent_->available_.begin() + entity_index_;
100 auto end_iterator = parent_->available_.end();
101 if(available_iterator != end_iterator)
103 while(available_iterator != end_iterator && *available_iterator)
105 ++available_iterator;
110 bool equal(iterator_impl
const& other)
const
112 return entity_index_ == other.entity_index_;
115 T& dereference()
const
117 return *parent_->get_component(get_entity().index());
140 return !(*available_);
147 return !(*available_);
152 data_ = data_begin_ + e.index();
153 available_ = available_begin_ + e.index();
154 return !(*available_);
157 value_type&
get()
const
159 return *
reinterpret_cast<value_type*
>(data_);
172 : available_begin_(&parent->available_[0])
173 , available_(&parent->available_[0])
174 , data_begin_(&parent->components_[0])
175 , data_(&parent->components_[0])
178 char const* available_begin_;
179 char const* available_;
180 typename dense_pool::element_t* data_begin_;
181 typename dense_pool::element_t* data_;
189 components_.resize(owner_pool.
size());
190 available_.resize(owner_pool.
size(),
true);
192 #if ENTITY_SUPPORT_VARIADICS
193 auto create_func = &dense_pool::create<T const&>;
206 boost::ref(default_value)
210 slots_.entity_create_handler =
213 &dense_pool::handle_create_entity,
220 slots_.entity_destroy_handler =
223 &dense_pool::handle_destroy_entity,
230 slots_.entity_swap_handler =
233 &dense_pool::handle_swap_entity,
242 #if ENTITY_SUPPORT_VARIADICS
243 template<
typename... Args>
246 slots_.entity_create_handler =
248 std::function<
void(
entity)>(
249 [
this, constructor_args...](
entity e)
251 create_entity_slot(e);
252 create(e, constructor_args...);
261 slots_.entity_create_handler =
263 std::function<
void(
entity)>(
264 [
this, default_value](
entity e)
266 create_entity_slot(e);
275 #if ENTITY_SUPPORT_VARIADICS
276 template<
typename... Args>
279 set_available(e.index(),
false);
280 T* ret_val = get_component(e.index());
281 new(ret_val) T(std::forward<Args>(args)...);
288 set_available(e.index(),
false);
289 T* ret_val = get_component(e.index());
290 new(ret_val) T(std::move(original));
298 BOOST_ASSERT(!is_available(e.index()) &&
"Trying to destroy un-allocated component.");
300 T* p = get_component(e.index());
303 set_available(e.index(),
true);
308 if(is_available(e.index()))
313 return get_component(e.index());
318 if(is_available(e.index()))
323 return get_component(e.index());
333 return iterator(
this, available_.size());
357 boost::signals2::scoped_connection entity_create_handler;
358 boost::signals2::scoped_connection entity_destroy_handler;
359 boost::signals2::scoped_connection entity_swap_handler;
364 return reinterpret_cast<T*
>(&components_[e]);
369 return reinterpret_cast<T*
>(&components_[e]);
374 return available_[idx] != 0;
379 available_[idx] = (available ==
true);
382 void create_entity_slot(
entity e)
384 components_.insert(components_.begin() + e.index(), element_t());
385 available_.emplace(available_.begin() + e.index(),
true);
388 void free_entity_slot(
entity e)
390 available_.erase(available_.begin() + e.index());
391 components_.erase(components_.begin() + e.index());
396 template<
typename Iter>
397 void create_range(Iter current, Iter last)
399 while(current != last)
401 create(current->first.lock().get(), std::move(current->second));
406 template<
typename Iter>
407 void destroy_range(Iter current, Iter last)
409 while(current != last)
411 destroy(current->lock().get());
418 void handle_create_entity(
entity e)
420 create_entity_slot(e);
423 void handle_destroy_entity(
entity e)
425 if(!is_available(e.index()))
446 create(b, std::move(*c_a));
451 create(a, std::move(*c_b));
456 std::vector<element_t> components_;
457 std::vector<char> available_;
458 std::size_t used_count_;
463 #endif // _ENTITY_COMPONENT_DENSEPOOL_H_INCLUDED_
T * create(entity e, Args &&...args)
boost::signals2::signal< void(entity)> on_entity_destroy
void swap(unique_entity &a, unique_entity &b)
std::size_t entity_index_t
dense_pool(entity_pool &owner_pool, T const &default_value=T())
bool is_entity(entity) const
boost::signals2::signal< void(entity)> on_entity_create
entity make_entity(entity_index_t idx) BOOST_NOEXCEPT_OR_NOTHROW
void for_each(EntityList const &entities, ComponentPoolTuple &&p, iterator_traits::is_incremental_tag, Fn f)
boost::signals2::signal< void(entity, entity)> on_entity_swap
void auto_create_components(entity_pool &owner_pool, Args &&...constructor_args)