entity
Entity/Component System for C++
zip.hpp
Go to the documentation of this file.
1 // ****************************************************************************
2 // entity/component/zip.hpp
3 //
4 // Creates a tuple of component views such that we
5 // can iterate over them as one iterator.
6 //
7 // Copyright Chris Glover 2014-2015
8 //
9 // Distributed under the Boost Software License, Version 1.0.
10 // See accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt
12 //
13 // ****************************************************************************
14 #pragma once
15 #ifndef _ENTITY_COMPONENT_ZIP_H_INCLUDED_
16 #define _ENTITY_COMPONENT_ZIP_H_INCLUDED_
17 
18 #include <boost/fusion/algorithm/iteration/fold.hpp>
19 #include <boost/fusion/algorithm/query/count.hpp>
20 #include <boost/fusion/algorithm/transformation/transform.hpp>
21 #include <boost/fusion/container/vector/convert.hpp>
22 #include <boost/fusion/sequence/intrinsic/at.hpp>
23 #include <boost/fusion/sequence/intrinsic/value_at.hpp>
24 #include <boost/mpl/aux_/preprocessed/gcc/placeholders.hpp>
25 #include <boost/mpl/transform.hpp>
26 #include <algorithm>
27 #include <cstddef>
28 #include <type_traits>
29 
30 #include "entity/config.hpp" // IWYU pragma: keep
31 #include "entity/entity.hpp"
33 
34 // ----------------------------------------------------------------------------
35 //
36 namespace entity { namespace component
37 {
38  namespace detail
39  {
40  template<typename ComponentPool>
42  {
43  typedef typename
44  std::decay<
45  ComponentPool
46  >::type::window type;
47  };
48 
49  template<typename ComponentPoolTuple>
51  {
52  typedef typename
53  boost::mpl::transform<
54  ComponentPoolTuple,
57  };
58 
60  {
62  : target_(target)
63  {}
64 
65  template<typename ComponentPoolWindow>
66  std::size_t operator()(std::size_t result, ComponentPoolWindow& view) const
67  {
68  return view.increment(target_) ? result + 1 : result;
69  }
70 
72  };
73 
75  {
77  : target_(target)
78  {}
79 
80  template<typename ComponentPoolWindow>
81  std::size_t operator()(std::size_t result, ComponentPoolWindow& view) const
82  {
83  return view.advance(target_) ? result + 1 : result;
84  }
85 
87  };
88  }
89 
90  // ------------------------------------------------------------------------
91  //
92  template<typename ComponentPoolTuple>
94  {
95  public:
96 
97  typedef typename
98  boost::fusion::result_of::as_vector<
100  ComponentPoolTuple
101  >::type
102  >::type windows_type;
103 
104  zipped_component_windows(ComponentPoolTuple&& pools)
105  {
106  windows_ = boost::fusion::as_vector(
107  boost::fusion::transform(
108  pools,
110  )
111  );
112  }
113 
114  std::size_t count()
115  {
116  return boost::fusion::count(windows_);
117  }
118 
119  std::size_t increment(entity e)
120  {
121  return boost::fusion::fold(
122  windows_,
123  0,
125  );
126  }
127 
128  std::size_t advance(entity e)
129  {
130  return boost::fusion::fold(
131  windows_,
132  0,
134  );
135  }
136 
137  windows_type get() const
138  {
139  return windows_;
140  }
141 
142  private:
143 
144  windows_type windows_;
145  };
146 
147  // ------------------------------------------------------------------------
148  //
149  template<typename T>
151  {
152  static const bool value = false;
153  };
154 
155  template<typename ComponentTuple>
157  {
158  static const bool value = true;
159  };
160 
161  // ------------------------------------------------------------------------
162  //
163  template<std::size_t idx, typename ZippedComponentWindows>
164  typename std::enable_if<
166  typename boost::fusion::result_of::value_at_c<
167  typename ZippedComponentWindows::windows_type, idx
168  >::type::value_type&
169  >::type get(ZippedComponentWindows const& windows)
170  {
171  return boost::fusion::at_c<idx>(windows.get()).get();
172  }
173 
174  template<typename ComponentPoolTuple>
176  {
178  ComponentPoolTuple
179  >(std::move(pools));
180  }
181 
182  // ------------------------------------------------------------------------
183  //
184 #if ENTITY_SUPPORT_VARIADICS
185  template<typename... Pools>
186  auto zip(Pools&... pools) -> decltype(zip_from_tuple(tie(pools...)))
187  {
188  return zip_from_tuple(tie(pools...));
189  }
190 #else
191  template<typename Pool>
192  auto zip(Pool& pool) -> decltype(zip_from_tuple(tie(pool)))
193  {
194  return zip_from_tuple(tie(pool));
195  }
196 
197  template<typename Pool1, typename Pool2>
198  auto zip(Pool1& pool_1, Pool2& pool_2) -> decltype(zip_from_tuple(tie(pool_1, pool_2)))
199  {
200  return zip_from_tuple(tie(pool_1, pool_2));
201  }
202 
203  template<typename Pool1, typename Pool2, typename Pool3>
204  auto zip(Pool1& pool_1, Pool2& pool_2, Pool3& pool_3) -> decltype(zip_from_tuple(tie(pool_1, pool_2, pool_3)))
205  {
206  return zip_from_tuple(tie(pool_1, pool_2, pool_3));
207  }
208 #endif
209 } } // namespace entity { namespace component {
210 
211 #endif // _ENTITY_COMPONENT_ZIP_H_INCLUDED_
boost::fusion::result_of::as_vector< typename detail::component_windows_type< ComponentPoolTuple >::type >::type windows_type
Definition: zip.hpp:102
boost::mpl::transform< ComponentPoolTuple, component_window_type< boost::mpl::_1 > >::type type
Definition: zip.hpp:56
std::decay< ComponentPool >::type::window type
Definition: zip.hpp:46
auto zip(Pools &...pools) -> decltype(zip_from_tuple(tie(pools...)))
Definition: zip.hpp:186
std::size_t operator()(std::size_t result, ComponentPoolWindow &view) const
Definition: zip.hpp:66
std::size_t operator()(std::size_t result, ComponentPoolWindow &view) const
Definition: zip.hpp:81
zipped_component_windows(ComponentPoolTuple &&pools)
Definition: zip.hpp:104
boost::fusion::vector< Pools &...> tie(Pools &...pools)
Definition: tie.hpp:28
zipped_component_windows< ComponentPoolTuple > zip_from_tuple(ComponentPoolTuple pools)
Definition: zip.hpp:175