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