entity
Entity/Component System for C++
for_each.hpp
Go to the documentation of this file.
1 // ****************************************************************************
2 // entity/algotithm/for_each.hpp
3 //
4 // Algorithm to call a functor for an entity with the supplied component
5 // types. If the entity does not have all of the supplied compnent types
6 // f is not called.
7 //
8 // Copyright Chris Glover 2014-2015
9 //
10 // Distributed under the Boost Software License, Version 1.0.
11 // See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt
13 //
14 // ****************************************************************************
15 #ifndef _ENTITY_ALGORITHM_FOREACH_H_INCLUDED_
16 #define _ENTITY_ALGORITHM_FOREACH_H_INCLUDED_
17 
18 #include <boost/fusion/algorithm/iteration/fold.hpp>
19 #include <boost/fusion/algorithm/query/all.hpp>
20 #include <boost/fusion/algorithm/transformation/transform.hpp>
21 #include <boost/fusion/container/vector/convert.hpp>
22 #include <boost/fusion/functional/invocation/invoke.hpp>
23 #include <algorithm>
24 
25 #include "entity/config.hpp" // IWYU pragma: keep
26 #include "entity/entity_range.hpp"
29 
30 // ----------------------------------------------------------------------------
31 //
32 namespace entity
33 {
34  // ------------------------------------------------------------------------
35  //
36  template<typename EntityList, typename ComponentPoolTuple, typename Fn>
37  void for_each(EntityList const& entities, ComponentPoolTuple&& p, iterator_traits::is_incremental_tag, Fn f)
38  {
39  auto i = begin(entities);
40  auto e = end(entities);
41 
42  auto c = boost::fusion::as_vector(
43  boost::fusion::transform(
44  std::forward<ComponentPoolTuple>(p),
46  )
47  );
48 
49  if(i != e)
50  {
51  if(boost::fusion::all(c, functional::is_entity(*i)))
52  {
54  f,
55  boost::fusion::transform(c, functional::get_component())
56  );
57  }
58 
59  ++i;
60  }
61 
62  for(; i != e; ++i)
63  {
64  if(boost::fusion::fold(c, true, functional::increment_window(*i)))
65  {
67  f,
68  boost::fusion::transform(c, functional::get_component())
69  );
70  }
71  }
72  }
73 
74  // ------------------------------------------------------------------------
75  //
76  template<typename EntityList, typename ComponentPoolTuple, typename Fn>
77  void for_each(EntityList const& entities, ComponentPoolTuple&& p, iterator_traits::is_skipping_tag, Fn f)
78  {
79  auto i = begin(entities);
80  auto e = end(entities);
81 
82  auto c = boost::fusion::as_vector(
83  boost::fusion::transform(
84  std::forward<ComponentPoolTuple>(p),
86  )
87  );
88 
89  if(i != e)
90  {
91  if(boost::fusion::all(c, functional::is_entity(*i)))
92  {
94  f,
95  boost::fusion::transform(c, functional::get_component())
96  );
97  }
98 
99  ++i;
100  }
101 
102  for(; i != e; ++i)
103  {
104  if(boost::fusion::fold(c, true, functional::advance_window(*i)))
105  {
107  f,
108  boost::fusion::transform(c, functional::get_component())
109  );
110  }
111  }
112  }
113 
114  template<typename EntityList, typename ComponentPoolTuple, typename Fn>
115  void for_each(EntityList const& entities, ComponentPoolTuple&& p, Fn f)
116  {
118  }
119 }
120 
121 #endif // _ENTITY_ALGORITHM_FOREACH_H_INCLUDED_
entity_pool::iterator end(entity_pool const &p)
void invoke(Fn f, Sequence< intrinsic_type & > &values)
Definition: invoke.hpp:32
entity_pool::iterator begin(entity_pool const &p)
void for_each(EntityList const &entities, ComponentPoolTuple &&p, iterator_traits::is_incremental_tag, Fn f)
Definition: for_each.hpp:37