16 #ifndef _ENTITY_COMPONENT_SPARSEPOOL_H_INCLUDED_
17 #define _ENTITY_COMPONENT_SPARSEPOOL_H_INCLUDED_
19 #include <boost/bind/bind.hpp>
20 #include <boost/bind/placeholders.hpp>
21 #include <boost/container/container_fwd.hpp>
22 #include <boost/container/flat_map.hpp>
23 #include <boost/ref.hpp>
24 #include <boost/iterator/iterator_facade.hpp>
25 #include <boost/signals2.hpp>
26 #include <boost/signals2/connection.hpp>
35 #include "entity/config.hpp"
41 struct forward_traversal_tag;
47 namespace entity {
namespace component
49 template<
typename ComponentPool>
51 template<
typename ComponentPool>
52 class destruction_queue;
58 : boost::iterator_facade<
61 , boost::forward_traversal_tag
66 return iterator_->first;
74 friend class boost::iterator_core_access;
77 typedef typename boost::container::flat_map<entity, T>::iterator parent_iterator;
79 explicit iterator_impl(parent_iterator convert_from)
80 : iterator_(std::move(convert_from))
88 bool equal(iterator_impl
const& other)
const
90 return iterator_ == other.iterator_;
93 T& dereference()
const
95 return iterator_->second;
98 parent_iterator iterator_;
117 return iterator_ != end_ && e == iterator_->first;
122 while(iterator_ != end_ && iterator_->first < target)
125 return iterator_ != end_ && iterator_->first == target;
133 value_type&
get()
const
135 return iterator_->second;
140 return iterator_ == end_;
147 typedef typename boost::container::flat_map<
151 window(parent_iterator start, parent_iterator
end)
152 : iterator_(
std::move(start))
153 , end_(
std::move(end))
156 parent_iterator iterator_;
157 parent_iterator end_;
164 #if ENTITY_SUPPORT_VARIADICS
165 auto create_func = &sparse_pool::create<T const&>;
178 boost::ref(default_value)
182 slots_.entity_destroy_handler =
185 &sparse_pool::handle_destroy_entity,
192 slots_.entity_swap_handler =
195 &sparse_pool::handle_swap_entity,
204 #if ENTITY_SUPPORT_VARIADICS
205 template<
typename... Args>
208 slots_.entity_create_handler =
210 std::function<
void(
entity)>(
211 [
this, constructor_args...](
entity e)
213 create(e, constructor_args...);
222 slots_.entity_create_handler =
235 #if ENTITY_SUPPORT_VARIADICS
236 template<
typename... Args>
239 auto r = components_.emplace(e, std::forward<Args>(args)...);
240 return &(r.first->second);
245 auto r = components_.emplace(e, std::move(original));
246 return &(r.first->second);
252 components_.erase(e);
257 auto obj = components_.find(e);
258 if(obj != components_.end())
268 auto obj = components_.find(e);
269 if(obj != components_.end())
279 return iterator(components_.begin());
289 return window(components_.begin(), components_.end());
294 return components_.size();
308 boost::signals2::scoped_connection entity_create_handler;
309 boost::signals2::scoped_connection entity_destroy_handler;
310 boost::signals2::scoped_connection entity_swap_handler;
315 template<
typename Iter>
316 void create_range(Iter first, Iter last)
318 std::vector<std::pair<entity, T>> entities;
319 std::transform(first, last, std::back_inserter(entities), [entities](std::pair<weak_entity, type>& h)
321 return std::make_pair(h.first.lock().get(), std::move(h.second));
324 components_.insert(boost::container::ordered_unique_range_t(), entities.begin(), entities.end());
327 template<
typename Iter>
328 void destroy_range(Iter current, Iter last)
330 while(current != last)
332 destroy(current->lock().get());
339 void handle_destroy_entity(
entity e)
347 auto c_a = components_.find(a);
348 auto c_b = components_.find(b);
349 auto end = components_.end();
351 if(c_a !=
end && c_b !=
end)
353 swap(c_a->second, c_b->second);
357 components_.emplace(b, std::move(c_a->second));
358 components_.erase(a);
362 components_.emplace(a, std::move(c_b->second));
363 components_.erase(b);
367 boost::container::flat_map<entity, T> components_;
372 #endif // _ENTITY_COMPONENT_SPARSEPOOL_H_INCLUDED_
boost::signals2::signal< void(entity)> on_entity_destroy
T * create(entity e, Args &&...args)
void auto_create_components(entity_pool &owner_pool, Args &&...constructor_args)
void swap(unique_entity &a, unique_entity &b)
sparse_pool(entity_pool &owner_pool, T const &default_value=T())
boost::signals2::signal< void(entity)> on_entity_create
bool advance(entity target)
void for_each(EntityList const &entities, ComponentPoolTuple &&p, iterator_traits::is_incremental_tag, Fn f)
bool is_entity(entity e) const
bool increment(entity target)
boost::signals2::signal< void(entity, entity)> on_entity_swap