Leviathan  0.8.0.0
Leviathan game engine
System.h
Go to the documentation of this file.
1 // Leviathan Game Engine
2 // Copyright (c) 2012-2018 Henri Hyyryläinen
3 #pragma once
4 #include "Define.h"
5 // ------------------------------------ //
6 #include "Common/ObjectPool.h"
7 #include "Component.h"
8 #include "EntityCommon.h"
9 #include "Exceptions.h"
10 #include "GameWorld.h"
11 #include "StateHolder.h"
12 
13 
14 namespace Leviathan {
15 
19 template<class T>
20 class CachedComponentCollectionHolder : public ObjectPool<T, ObjectID> {};
21 
24 template<class UsedCachedComponentCollectionT>
26 public:
28 
29  void Clear()
30  {
31 
33  }
34 
36  {
38  }
39 
40  // TODO: do something about the amount of copy pasting done here
41 
42 
46  template<class FirstType, class SecondType>
48  ObjectPool<std::tuple<FirstType&, SecondType&>, ObjectID>& CachedComponentCollections,
49  const std::vector<std::tuple<FirstType*, ObjectID>>& firstdata,
50  const std::vector<std::tuple<SecondType*, ObjectID>>& seconddata,
51  const ComponentHolder<FirstType>& firstholder,
52  const ComponentHolder<SecondType>& secondholder)
53  {
54  // First way around //
55  for(auto iter = firstdata.begin(); iter != firstdata.end(); ++iter) {
56 
57  const auto id = std::get<1>(*iter);
58  SecondType* other = _TupleHelperGetIfComponentExists(id, seconddata, secondholder);
59 
60  // Create node if required components where found and it doesn't exist already //
61  if(!other || CachedComponentCollections.Find(id) != nullptr)
62  continue;
63 
64  CachedComponentCollections.ConstructNew(id, *std::get<0>(*iter), *other);
65  }
66 
67  // And the other way around //
68  for(auto iter = seconddata.begin(); iter != seconddata.end(); ++iter) {
69 
70  const auto id = std::get<1>(*iter);
71  FirstType* other = _TupleHelperGetIfComponentExists(id, firstdata, firstholder);
72 
73  // Create node if required components where found and it doesn't exist already //
74  if(!other || CachedComponentCollections.Find(id) != nullptr)
75  continue;
76 
77  CachedComponentCollections.ConstructNew(id, *other, *std::get<0>(*iter));
78  }
79  }
80 
82  template<class FirstType, class SecondType, class ThirdType>
84  ObjectPool<std::tuple<FirstType&, SecondType&, ThirdType&>, ObjectID>&
85  CachedComponentCollections,
86  const std::vector<std::tuple<FirstType*, ObjectID>>& firstdata,
87  const std::vector<std::tuple<SecondType*, ObjectID>>& seconddata,
88  const std::vector<std::tuple<ThirdType*, ObjectID>>& thirddata,
89  const ComponentHolder<FirstType>& firstholder,
90  const ComponentHolder<SecondType>& secondholder,
91  const ComponentHolder<ThirdType>& thirdholder)
92  {
93  // First way around //
94  for(auto iter = firstdata.begin(); iter != firstdata.end(); ++iter) {
95 
96  const auto id = std::get<1>(*iter);
97  SecondType* other2 =
98  _TupleHelperGetIfComponentExists(id, seconddata, secondholder);
99  ThirdType* other3 = _TupleHelperGetIfComponentExists(id, thirddata, thirdholder);
100 
101  // Create node if required components where found and it doesn't exist already //
102  if(!other2 || !other3 || CachedComponentCollections.Find(id) != nullptr)
103  continue;
104 
105  CachedComponentCollections.ConstructNew(id, *std::get<0>(*iter), *other2, *other3);
106  }
107 
108  // And the other way around //
109  for(auto iter = seconddata.begin(); iter != seconddata.end(); ++iter) {
110 
111  const auto id = std::get<1>(*iter);
112  FirstType* other1 = _TupleHelperGetIfComponentExists(id, firstdata, firstholder);
113  ThirdType* other3 = _TupleHelperGetIfComponentExists(id, thirddata, thirdholder);
114 
115  // Create node if required components where found and it doesn't exist already //
116  if(!other1 || !other3 || CachedComponentCollections.Find(id) != nullptr)
117  continue;
118 
119  CachedComponentCollections.ConstructNew(id, *other1, *std::get<0>(*iter), *other3);
120  }
121 
122  // Third way around //
123  for(auto iter = thirddata.begin(); iter != thirddata.end(); ++iter) {
124 
125  const auto id = std::get<1>(*iter);
126  FirstType* other1 = _TupleHelperGetIfComponentExists(id, firstdata, firstholder);
127  SecondType* other2 =
128  _TupleHelperGetIfComponentExists(id, seconddata, secondholder);
129 
130  // Create node if required components where found and it doesn't exist already //
131  if(!other1 || !other2 || CachedComponentCollections.Find(id) != nullptr)
132  continue;
133 
134  CachedComponentCollections.ConstructNew(id, *other1, *other2, *std::get<0>(*iter));
135  }
136  }
137 
138 protected:
139  // Helpers for TupleCachedComponentCollectionHelper //
140  template<class T>
142  const std::vector<std::tuple<T*, ObjectID>>& addedlist,
143  const ComponentHolder<T>& holder)
144  {
145  // First search added //
146  for(auto iter = addedlist.begin(); iter != addedlist.end(); ++iter) {
147 
148  if(std::get<1>(*iter) == id) {
149 
150  return std::get<0>(*iter);
151  }
152  }
153 
154  // This full search returns a nullptr if not found //
155  return holder.Find(id);
156  }
157 
158 public:
160 };
161 
167 template<class UsedCachedComponentCollection>
168 class System : public SystemCachedComponentCollectionStorage<UsedCachedComponentCollection> {
169 public:
170  /* Template for node run method, copy-paste and fill in the parameters
171 
172  void Run(GameWorld &world){
173 
174  auto& index = CachedComponents.GetIndex();
175  for(auto iter = index.begin(); iter != index.end(); ++iter){
176 
177  this->ProcessCachedComponents(*iter->second, iter->first, );
178  }
179  */
180 };
181 
184 template<class UsedComponent>
186 public:
187  // Example run method
188  // void Run(GameWorld &world, std::unordered_map<ObjectID, UsedComponent*> &index);
189 };
190 
192 template<class UsedComponent, class ComponentState>
194 public:
195  void Run(GameWorld& world, std::unordered_map<ObjectID, UsedComponent*>& index,
196  StateHolder<ComponentState>& heldstates, int worldtick)
197  {
198  // TODO: find a better way (see the comment a few lines down why this is here)
199  if(!world.GetNetworkSettings().DoInterpolation)
200  return;
201 
202  const bool authoritative = world.GetNetworkSettings().IsAuthoritative;
203 
204  for(auto iter = index.begin(); iter != index.end(); ++iter) {
205  auto& component = *iter->second;
206 
207  if(!component.Marked)
208  continue;
209 
210  // And only for locally controlled entities
211  if(!authoritative && !world.IsUnderOurLocalControl(iter->first))
212  continue;
213 
214  // Ignore creating states on the server when using local control as that causes
215  // issues Actually this whole system is disabled when interpolating isn't needed
216 
217  // Needs a new state //
218  if(heldstates.CreateStateIfChanged(iter->first, component, worldtick)) {
219 
220  component.StateMarked = true;
221  }
222 
223  component.Marked = false;
224  }
225  }
226 };
227 
228 
229 } // namespace Leviathan
static void TupleCachedComponentCollectionHelper(ObjectPool< std::tuple< FirstType &, SecondType &>, ObjectID > &CachedComponentCollections, const std::vector< std::tuple< FirstType *, ObjectID >> &firstdata, const std::vector< std::tuple< SecondType *, ObjectID >> &seconddata, const ComponentHolder< FirstType > &firstholder, const ComponentHolder< SecondType > &secondholder)
Helper function for creating nodes based on std::tuple.
Definition: System.h:47
bool CreateStateIfChanged(ObjectID id, const ComponentT &component, int ticknumber)
Creates a new state for entity&#39;s component if it has changed.
Definition: StateHolder.h:182
void Clear()
Clears the index and replaces the pool with a new one.
Definition: ObjectPool.h:249
int32_t ObjectID
Definition: EntityCommon.h:11
static void TupleCachedComponentCollectionHelper(ObjectPool< std::tuple< FirstType &, SecondType &, ThirdType &>, ObjectID > &CachedComponentCollections, const std::vector< std::tuple< FirstType *, ObjectID >> &firstdata, const std::vector< std::tuple< SecondType *, ObjectID >> &seconddata, const std::vector< std::tuple< ThirdType *, ObjectID >> &thirddata, const ComponentHolder< FirstType > &firstholder, const ComponentHolder< SecondType > &secondholder, const ComponentHolder< ThirdType > &thirdholder)
Tree part component TupleCachedComponentCollectionHelper.
Definition: System.h:83
static T * _TupleHelperGetIfComponentExists(ObjectID id, const std::vector< std::tuple< T *, ObjectID >> &addedlist, const ComponentHolder< T > &holder)
Definition: System.h:141
DLLEXPORT const auto & GetNetworkSettings() const
Definition: GameWorld.h:345
auto GetObjectCount() const
Definition: ObjectPool.h:264
Base class for all systems that create states from changed components.
Definition: System.h:193
Base for all entity component related systems.
Definition: System.h:168
Base class for systems that use a single component directly.
Definition: System.h:185
DLLEXPORT bool IsUnderOurLocalControl(ObjectID id)
Definition: GameWorld.h:398
Holds state objects of type for quick access by ObjectID.
Definition: GameWorld.h:36
The access mask controls which registered functions and classes a script sees.
Definition: GameModule.h:12
void Run(GameWorld &world, std::unordered_map< ObjectID, UsedComponent *> &index, StateHolder< ComponentState > &heldstates, int worldtick)
Definition: System.h:195
Creates objects in a shared memory region.
Definition: ObjectPool.h:93
Represents a world that contains entities.
Definition: GameWorld.h:99