Cafu Engine
Entity.hpp
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_GAMESYS_ENTITY_HPP_INCLUDED
8 #define CAFU_GAMESYS_ENTITY_HPP_INCLUDED
9 
10 #include "CompBasics.hpp"
11 #include "CompTransform.hpp"
12 
13 #include "Templates/Array.hpp"
14 #include "Templates/Pointer.hpp"
15 
16 #include <climits>
17 
18 
19 struct CaKeyboardEventT;
20 struct CaMouseEventT;
21 struct lua_State;
22 struct luaL_Reg;
23 namespace cf { namespace TypeSys { class TypeInfoT; } }
24 namespace cf { namespace TypeSys { class TypeInfoManT; } }
25 namespace cf { namespace TypeSys { class CreateParamsT; } }
26 namespace cf { namespace TypeSys { class MethsDocT; } }
27 
28 
29 namespace cf
30 {
31  namespace GameSys
32  {
33  class EntityCreateParamsT;
34  class WorldT;
35 
36 
37  /// The TypeInfoTs of all EntityT derived classes must register with this TypeInfoManT instance.
38  cf::TypeSys::TypeInfoManT& GetGameSysEntityTIM();
39 
40 
41  /**
42  * This class represents game entities, which are the basic elements of a world.
43  *
44  * EntityT instances can be created in C++ code or in Lua scripts, using the world:new() function.
45  * They can be passed from C++ code to Lua and from Lua to C++ code at will.
46  * In C++ code, all EntityT instances are kept in IntrusivePtrT's. Their lifetime is properly managed:
47  * An entity is deleted automatically when it is no longer used in Lua \emph{and} in C++.
48  * That is, code like
49  * Example 1: w = world:new("EntityT"); world:SetRootEntity(w); w = nil;
50  * Example 2: w = world:new("EntityT"); w:AddChild(world:new("EntityT"));
51  * works as expected. See the cf::ScriptBinderT class for technical and implementation details.
52  */
53  class EntityT : public RefCountedT
54  {
55  public:
56 
57  /// The normal constructor.
58  /// @param Params The creation parameters for the entity.
59  EntityT(const EntityCreateParamsT& Params);
60 
61  /// The copy constructor. It creates a new entity as a copy of another entity.
62  /// The parent of the copy is always `NULL`, and it is up to the caller to insert the copy
63  /// somewhere into an entity hierarchy.
64  ///
65  /// @param Entity The entity to copy-construct this entity from.
66  /// @param Recursive Whether to recursively copy all children as well.
67  EntityT(const EntityT& Entity, bool Recursive=false);
68 
69  /// The virtual copy constructor.
70  /// Callers can use this method to create a copy of this entity without knowing its concrete type.
71  /// Overrides in derived classes use a covariant return type to facilitate use when the concrete
72  /// type is known.
73  ///
74  /// @param Recursive Whether to recursively clone all children of this entity as well.
75  virtual EntityT* Clone(bool Recursive=false) const;
76 
77  /// The virtual destructor. Deletes this entity and all its children.
78  virtual ~EntityT();
79 
80 
81  WorldT& GetWorld() const { return m_World; }
82 
83  /// Returns the ID of this entity.
84  /// The ID is unique in the world, and used to unambiguously identify the entity in network messages
85  /// and as entity index number into `.cw` world files.
86  unsigned int GetID() const { return m_ID; }
87 
88  /// Returns the parent entity of this entity.
89  IntrusivePtrT<EntityT> GetParent() const { return m_Parent; }
90 
91  /// Returns the immediate children of this entity.
92  /// This is analogous to calling GetChildren(Chld, false) with an initially empty Chld array.
93  const ArrayT< IntrusivePtrT<EntityT> >& GetChildren() const { return m_Children; }
94 
95  /// Returns the children of this entity.
96  /// @param Chld The array to which the children of this entity are appended. Note that Chld gets *not* initially cleared by this function!
97  /// @param Recurse Determines if also the grand-children, grand-grand-children etc. are returned.
98  void GetChildren(ArrayT< IntrusivePtrT<EntityT> >& Chld, bool Recurse=false) const;
99 
100  /// Traverses the hierarchy (sub-tree) that is rooted at this entity in depth-first order
101  /// and records all encountered entities in the given list.
102  /// @param List All nodes in this sub-tree are added to this list in depth-first order.
103  void GetAll(ArrayT< IntrusivePtrT<EntityT> >& List);
104 
105  /// Adds the given entity to the children of this entity, and sets this entity as the parent of the child.
106  ///
107  /// This method also makes sure that the name of the Child is unique among its siblings,
108  /// modifying it as necessary. See SetName() for more details.
109  ///
110  /// @param Child The entity to add to the children of this entity.
111  /// @param Pos The position among the children to insert the child entity at.
112  /// @returns true on success, false on failure (Child has a parent already, or is the root of this entity).
113  bool AddChild(IntrusivePtrT<EntityT> Child, unsigned long Pos=0xFFFFFFFF);
114 
115  /// Removes the given entity from the children of this entity.
116  /// @param Child The entity to remove from the children of this entity.
117  /// @returns true on success, false on failure (Child is not a child of this entity).
119 
120  /// Returns the top-most parent of this entity, that is, the root of the hierarchy that this entity is in.
121  IntrusivePtrT<EntityT> GetRoot(); // Method cannot be const because return type is not const -- see implementation.
122 
123 
124  /// Returns the application component of this entity.
125  /// This component is much like the "Basics" and "Transform" components, but it can be set by the
126  /// application (see SetApp()), and is intended for the sole use by the application, e.g. for
127  /// implementing a "selection gizmo" in the Map Editor.
129 
130  /// The `const` variant of the GetApp() method above. See GetApp() for details.
131  IntrusivePtrT<const ComponentBaseT> GetApp() const { return m_App; }
132 
133  /// Sets the application component for this entity. See GetApp() for details.
135 
136  /// Returns the "Basics" component of this entity.
137  /// The "Basics" component defines the name and the "show" flag of the entity.
138  IntrusivePtrT<ComponentBasicsT> GetBasics() const { return m_Basics; }
139 
140  /// Returns the "Transform" component of this entity.
141  /// The "Transform" component defines the position, size and orientation of the entity.
142  IntrusivePtrT<ComponentTransformT> GetTransform() const { return m_Transform; }
143 
144 
145  /// Returns the components that this entity is composed of.
146  /// Only the "custom" components are returned, does *not* include the application component,
147  /// "Basics" or "Transform".
148  const ArrayT< IntrusivePtrT<ComponentBaseT> >& GetComponents() const { return m_Components; }
149 
150  /// Returns the (`n`-th) component of the given (type) name.
151  /// Covers both the "custom" as well as the fixed components (application, "Basics" and "Transform").
152  /// That is, `GetComponent("Basics") == GetBasics()` and `GetComponent("Transform") == GetTransform()`.
153  IntrusivePtrT<ComponentBaseT> GetComponent(const std::string& TypeName, unsigned int n=0) const;
154 
155  /// Returns the `n`-th component of this entity, covering both the "custom" as well
156  /// as the fixed components (application, "Basics" and "Transform").
157  /// This method facilitates looping over all of the entity's components, especially
158  /// when neither their concrete type nor their concrete order are paramount.
159  IntrusivePtrT<ComponentBaseT> GetComponent(unsigned int n) const;
160 
161  /// Adds the given component to this entity.
162  ///
163  /// @param Comp The component to add to this entity.
164  /// @param Index The position among the other components to insert `Comp` at.
165  /// @returns `true` on success, `false` on failure (if `Comp` is part of an entity already).
166  bool AddComponent(IntrusivePtrT<ComponentBaseT> Comp, unsigned long Index=ULONG_MAX);
167 
168  /// Deletes the component at the given index from this entity.
169  void DeleteComponent(unsigned long CompNr);
170 
171 
172  /// Finds the entity with the given ID in the hierachy tree of this entity.
173  /// Use `GetRoot()->Find(xy)` in order to search the entire world for the entity with ID `xy`.
174  ///
175  /// Note that the method cannot be `const` because the return type is not `const` (see the implementation
176  /// for details).
177  ///
178  /// @param WantedID The ID of the entity that is to be found.
179  /// @returns The pointer to the desired entity, or `NULL` if no entity with this ID exists.
180  IntrusivePtrT<EntityT> FindID(unsigned int WantedID);
181 
182  /// Finds the entity with the name WantedName in the hierachy tree of this entity.
183  /// Use `GetRoot()->Find("xy")` in order to search the entire world for the entity with name `xy`.
184  ///
185  /// Note that the method cannot be `const` because the return type is not `const` (see the implementation
186  /// for details).
187  ///
188  /// @param WantedName The name of the entity that is to be found.
189  /// @returns The pointer to the desired entity, or `NULL` if no entity with this name exists.
190  IntrusivePtrT<EntityT> Find(const std::string& WantedName);
191 
192  /// Finds all entities in the hierachy tree of this entity that have at least one component of the given
193  /// (type) name. Use `GetRoot()->FindByComponent("xy")` in order to search the entire world for entities
194  /// with component `xy`.
195  ///
196  /// Note that the method cannot be `const` because the return type is not `const` (see the implementation
197  /// for details).
198  ///
199  /// @param TypeName The type name of the component that found entities must have.
200  /// @param Result All found entities are appended to this array.
201  void FindByComponent(const std::string& TypeName, ArrayT< IntrusivePtrT<EntityT> >& Result);
202 
203  /// Returns whether the given entity is in the hierarchy (sub-tree) of this entity.
204  bool Has(IntrusivePtrT<EntityT> Ent) const;
205 
206  /// Returns a bounding-box that encloses the visual representation of this entity.
207  /// It is used to determine if the entity is in the view-frustum of a camera, how large a region must be
208  /// updated in the 2D views of a Map Editor, if the entity is in the potentially-visibility-set (PVS) of
209  /// another entity, and similar purposes.
210  ///
211  /// This method does *not* recurse: The returned bounding-box covers this entity, but not its children.
212  ///
213  /// Note that many details are up to the entity's components, whose GetCullingBB() method this method's
214  /// implementation calls. For example, it is up to the Map Editor's "App" component to decide whether
215  /// it includes selection gizmo handles and/or the map primitives in the returned bounding-box.
216  ///
217  /// @param WorldSpace If `true`, the bounding-box is returned in world-space coordinates.
218  /// If `false`, the bounding-box is returned in local entity-space.
219  /// Note that due to the transformation, the volume of the bounding-box in world-space
220  /// may be larger than the volume of the bounding-box in entity-space.
221  ///
222  /// @return The bounding-box that encloses the visual representation of this entity. The returned
223  /// bounding-box is always valid, but possibly not inited (`!IsInited()`), indicating that the entity
224  /// doesn't have a visual representation.
225  BoundingBox3fT GetCullingBB(bool WorldSpace) const;
226 
227  /// Writes the current state of this entity into the given stream.
228  /// This method is called to send the state of the entity over the network, to save it to disk,
229  /// or to store it in the clipboard.
230  ///
231  /// @param Stream
232  /// The stream to write the state data to.
233  ///
234  /// @param WithChildren
235  /// Should the children be recursively serialized as well?
236  void Serialize(cf::Network::OutStreamT& Stream, bool WithChildren=false) const;
237 
238  /// Reads the state of this entity from the given stream, and updates the entity accordingly.
239  /// This method is called after the state of the entity has been received over the network,
240  /// has been loaded from disk, has been read from the clipboard, or must be "reset" for the purpose
241  /// of (re-)prediction.
242  ///
243  /// @param Stream
244  /// The stream to read the state data from.
245  ///
246  /// @param IsIniting
247  /// Used to indicate that the call is part of the construction / first-time initialization of the entity.
248  /// The implementation will use this to not wrongly process the event counters, interpolation, etc.
249  void Deserialize(cf::Network::InStreamT& Stream, bool IsIniting);
250 
251  /// Renders the components of this entity.
252  /// Note that this method does *not* recurse into the children, and it does *not* setup any of the
253  /// MatSys's model, view or projection matrices: it's up to the caller to do that.
254  /// @param FirstPersonView If the world is rendered from the perspective of this entity.
255  /// @param LodDist The distance of the viewer entity to this entity.
256  /// @returns `true` if "something" was rendered, `false` otherwise (in this case the Map Editor may choose
257  /// to render another visual representation of this component's entity).
258  bool RenderComponents(bool FirstPersonView, float LodDist) const;
259 
260  /// Keyboard input event handler.
261  /// @param KE Keyboard event.
262  virtual bool OnInputEvent(const CaKeyboardEventT& KE);
263 
264  /// Mouse input event handler.
265  /// @param ME Mouse event.
266  /// @param PosX Mouse position x.
267  /// @param PosY Mouse position y.
268  virtual bool OnInputEvent(const CaMouseEventT& ME, float PosX, float PosY);
269 
270  /// Advances the entity one frame (one "clock-tick") on the server.
271  /// It typically updates all game-relevant state that is sync'ed over the network to all
272  /// connected game clients.
273  /// ComponentBaseT::OnServerFrame() is called by this method for all components of this entity.
274  ///
275  /// @param t The time in seconds since the last server frame.
276  void OnServerFrame(float t);
277 
278  /// Advances the entity one frame (one "clock-tick") on the client.
279  /// It typically updates eye-candy that is *not* sync'ed over the network.
280  /// ComponentBaseT::OnClientFrame() is called by this method for all components of this entity.
281  ///
282  /// @param t The time in seconds since the last client frame.
283  void OnClientFrame(float t);
284 
285  /// Calls the Lua method with name `MethodName` of this entity.
286  /// This method is analogous to UniScriptStateT::CallMethod(), see there for details.
287  /// @param MethodName The name of the Lua method to call.
288  /// @param NumExtraArgs The number of extra arguments that have been pushed on the stack.
289  /// @param Signature See UniScriptStateT::Call() for details.
290  bool CallLuaMethod(const char* MethodName, int NumExtraArgs, const char* Signature="", ...);
291 
292 
293  // The TypeSys related declarations for this class.
294  virtual const cf::TypeSys::TypeInfoT* GetType() const { return &TypeInfo; }
295  static void* CreateInstance(const cf::TypeSys::CreateParamsT& Params);
296  static const cf::TypeSys::TypeInfoT TypeInfo;
297 
298 
299  protected:
300 
301  // Methods called from Lua scripts on cf::GameSys::EntityT instances.
302  // They are protected so that derived entity classes can access them when implementing overloads.
303  static int GetID(lua_State* LuaState);
304  static int AddChild(lua_State* LuaState);
305  static int RemoveChild(lua_State* LuaState);
306  static int GetParent(lua_State* LuaState);
307  static int GetRoot(lua_State* LuaState);
308  static int GetChildren(lua_State* LuaState);
309  static int FindByID(lua_State* LuaState);
310  static int FindByName(lua_State* LuaState);
311  static int FindByComponent(lua_State* LuaState);
312  static int GetBasics(lua_State* LuaState);
313  static int GetTransform(lua_State* LuaState);
314  static int AddComponent(lua_State* LuaState);
315  static int RmvComponent(lua_State* LuaState);
316  static int GetComponents(lua_State* LuaState);
317  static int GetComponent(lua_State* LuaState);
318  static int toString(lua_State* LuaState);
319 
320  static const luaL_Reg MethodsList[]; ///< List of methods registered with Lua.
321  static const char* DocClass;
322  static const cf::TypeSys::MethsDocT DocMethods[];
323  static const cf::TypeSys::MethsDocT DocCallbacks[];
324 
325 
326  private:
327 
328  void UpdateAllDependencies(); ///< Updates the dependencies of all components.
329  void operator = (const EntityT&); ///< Use of the Assignment Operator is not allowed.
330 
331  WorldT& m_World; ///< The world instance in which this entity was created and exists. Useful in many regards, but especially for access to the commonly used resources, the script state, etc.
332  const unsigned int m_ID; ///< The ID of this entity. It is unique in the `m_World`, and used to unambiguously identify the entity in network messages and as entity index number into `.cw` world files.
333  EntityT* m_Parent; ///< The parent of this entity. May be NULL if there is no parent. In order to not create cycles of IntrusivePtrT's, the type is intentionally a raw pointer only.
334  ArrayT< IntrusivePtrT<EntityT> > m_Children; ///< The list of children of this entity.
335  IntrusivePtrT<ComponentBaseT> m_App; ///< A component for the sole use by the application / implementation.
336  IntrusivePtrT<ComponentBasicsT> m_Basics; ///< The component that defines the name and the "show" flag of this entity.
337  IntrusivePtrT<ComponentTransformT> m_Transform; ///< The component that defines the position and orientation of this entity.
338  ArrayT< IntrusivePtrT<ComponentBaseT> > m_Components; ///< The components that this entity is composed of.
339  };
340  }
341 }
342 
343 #endif
bool RemoveChild(IntrusivePtrT< EntityT > Child)
Removes the given entity from the children of this entity.
Definition: Entity.cpp:167
This class implements smart (reference-counted) pointers.
Definition: Pointer.hpp:43
virtual bool OnInputEvent(const CaKeyboardEventT &KE)
Keyboard input event handler.
Definition: Entity.cpp:556
const ArrayT< IntrusivePtrT< ComponentBaseT > > & GetComponents() const
Returns the components that this entity is composed of.
Definition: Entity.hpp:148
bool AddChild(IntrusivePtrT< EntityT > Child, unsigned long Pos=0xFFFFFFFF)
Adds the given entity to the children of this entity, and sets this entity as the parent of the child...
Definition: Entity.cpp:143
Creation parameters for a game entity.
Definition: EntityCreateParams.hpp:21
void SetApp(IntrusivePtrT< ComponentBaseT > App)
Sets the application component for this entity. See GetApp() for details.
Definition: Entity.cpp:222
This struct describes a mouse event.
Definition: OpenGLWindow.hpp:185
EntityT(const EntityCreateParamsT &Params)
The normal constructor.
Definition: Entity.cpp:55
virtual ~EntityT()
The virtual destructor. Deletes this entity and all its children.
Definition: Entity.cpp:112
IntrusivePtrT< ComponentBasicsT > GetBasics() const
Returns the "Basics" component of this entity.
Definition: Entity.hpp:138
This class represents game entities, which are the basic elements of a world.
Definition: Entity.hpp:53
bool AddComponent(IntrusivePtrT< ComponentBaseT > Comp, unsigned long Index=ULONG_MAX)
Adds the given component to this entity.
Definition: Entity.cpp:283
virtual EntityT * Clone(bool Recursive=false) const
The virtual copy constructor.
Definition: Entity.cpp:106
IntrusivePtrT< ComponentBaseT > GetApp()
Returns the application component of this entity.
Definition: Entity.hpp:128
void DeleteComponent(unsigned long CompNr)
Deletes the component at the given index from this entity.
Definition: Entity.cpp:297
const ArrayT< IntrusivePtrT< EntityT > > & GetChildren() const
Returns the immediate children of this entity.
Definition: Entity.hpp:93
This class is used for reading data from a StateT instance (deserialization).
Definition: State.hpp:207
bool RenderComponents(bool FirstPersonView, float LodDist) const
Renders the components of this entity.
Definition: Entity.cpp:532
Definition: World.hpp:85
BoundingBox3fT GetCullingBB(bool WorldSpace) const
Returns a bounding-box that encloses the visual representation of this entity.
Definition: Entity.cpp:364
IntrusivePtrT< ComponentBaseT > GetComponent(const std::string &TypeName, unsigned int n=0) const
Returns the (n-th) component of the given (type) name.
Definition: Entity.cpp:234
This class manages the type infos.
Definition: TypeSys.hpp:145
IntrusivePtrT< EntityT > GetRoot()
Returns the top-most parent of this entity, that is, the root of the hierarchy that this entity is in...
Definition: Entity.cpp:211
void OnClientFrame(float t)
Advances the entity one frame (one "clock-tick") on the client.
Definition: Entity.cpp:612
unsigned int GetID() const
Returns the ID of this entity.
Definition: Entity.hpp:86
This class is used for writing data into a StateT instance (serialization).
Definition: State.hpp:81
This struct describes a keyboard event.
Definition: OpenGLWindow.hpp:20
void OnServerFrame(float t)
Advances the entity one frame (one "clock-tick") on the server.
Definition: Entity.cpp:599
IntrusivePtrT< const ComponentBaseT > GetApp() const
The const variant of the GetApp() method above. See GetApp() for details.
Definition: Entity.hpp:131
IntrusivePtrT< EntityT > FindID(unsigned int WantedID)
Finds the entity with the given ID in the hierachy tree of this entity.
Definition: Entity.cpp:309
bool CallLuaMethod(const char *MethodName, int NumExtraArgs, const char *Signature="",...)
Calls the Lua method with name MethodName of this entity.
Definition: Entity.cpp:625
This class holds the hierarchy of game entities that populate a game world.
Definition: World.hpp:39
void Deserialize(cf::Network::InStreamT &Stream, bool IsIniting)
Reads the state of this entity from the given stream, and updates the entity accordingly.
Definition: Entity.cpp:435
void GetAll(ArrayT< IntrusivePtrT< EntityT > > &List)
Traverses the hierarchy (sub-tree) that is rooted at this entity in depth-first order and records all...
Definition: Entity.cpp:202
IntrusivePtrT< EntityT > GetParent() const
Returns the parent entity of this entity.
Definition: Entity.hpp:89
void FindByComponent(const std::string &TypeName, ArrayT< IntrusivePtrT< EntityT > > &Result)
Finds all entities in the hierachy tree of this entity that have at least one component of the given ...
Definition: Entity.cpp:341
IntrusivePtrT< EntityT > Find(const std::string &WantedName)
Finds the entity with the name WantedName in the hierachy tree of this entity.
Definition: Entity.cpp:325
bool Has(IntrusivePtrT< EntityT > Ent) const
Returns whether the given entity is in the hierarchy (sub-tree) of this entity.
Definition: Entity.cpp:351
Definition: Renderer.hpp:16
void Serialize(cf::Network::OutStreamT &Stream, bool WithChildren=false) const
Writes the current state of this entity into the given stream.
Definition: Entity.cpp:403
Definition: TypeSys.hpp:52
Definition: TypeSys.hpp:57
This class keeps type information (about an entity class that occurs in the game).
Definition: TypeSys.hpp:79
IntrusivePtrT< ComponentTransformT > GetTransform() const
Returns the "Transform" component of this entity.
Definition: Entity.hpp:142
A base class for objects that are reference-counted with IntrusivePtrTs.
Definition: Pointer.hpp:13
static const luaL_Reg MethodsList[]
List of methods registered with Lua.
Definition: Entity.hpp:320