StevEngine
StevEngine is a customizable C++ game engine.
Loading...
Searching...
No Matches
GameObject.hpp
1#pragma once
2#include "main/EventSystem.hpp"
3#include "utilities/ID.hpp"
4#include "utilities/Vector3.hpp"
5#include "utilities/Quaternion.hpp"
6#include "utilities/Matrix4.hpp"
7#include "main/Log.hpp"
8#include "main/Component.hpp"
9
10#include <memory>
11#include <vector>
12#include <type_traits>
13
14namespace StevEngine {
15 //Child Events
20 template<typename EventType>
21 class ChildEvent : public Event {
22 public:
23 ChildEvent(const EventType& event) : event(event) {};
24 const EventType& event;
25 const std::string GetEventType() const override { return GetStaticEventType(); };
26 static const std::string GetStaticEventType() { return "Child" + EventType::GetStaticEventType(); }
27 };
28
35 class GameObject final {
36 friend class SceneManager;
37 friend class Scene;
38 //Basic properties
39 public:
41 std::string name;
42
47 Utilities::ID Id() const { return id; }
48
49 private:
50 Utilities::ID id;
51 std::string scene;
52 bool isActive = false;
53
54 //Transform
55 public:
61
67
73
74 //Update properties
80 void SetPosition(Utilities::Vector3 position, bool announce = true);
81
87 void SetRotation(Utilities::Quaternion rotation, bool announce = true);
88
94 void SetScale(Utilities::Vector3 scale, bool announce = true);
95
103 void SetTransform(Utilities::Vector3 position, Utilities::Quaternion rotation, Utilities::Vector3 scale, bool announce = true);
104
105 //World space properties
111
117
123
124 private:
128
129 //Main functions
130 public:
131 ~GameObject();
132
138 Utilities::Stream Export(Utilities::StreamType type) const;
139
144 void Import(Utilities::Stream& stream);
145
146 private:
150 void Start();
151
155 void Deactivate();
156
161 void Update(double deltaTime);
162
163 #ifdef StevEngine_SHOW_WINDOW
168 void Draw(Utilities::Matrix4 transform);
169 #endif
170
171 public:
177 GameObject(Utilities::ID id, std::string name, std::string scene);
178
179 //Events
180 public:
188 template<typename EventType>
189 Utilities::ID Subscribe(EventFunction<EventType> handler, bool allowFromChild = true) {
190 if(allowFromChild)
191 events.Subscribe<ChildEvent<EventType>>([handler] (ChildEvent<EventType> e) { handler(e.event); });
192 return events.Subscribe<EventType>(handler);
193 }
194
200 template<typename EventType>
201 void Publish(const EventType& event) {
202 events.Publish(event);
203 if(HasParent()) GetParent().ChildPublish<EventType>(event, id);
204 }
205
211 void Unsubscribe(const std::string eventId, const Utilities::ID handlerId) { events.Unsubscribe(eventId, handlerId); }
212
213 private:
220 template<typename EventType>
221 void ChildPublish(const EventType& event, Utilities::ID object) {
222 events.Publish(ChildEvent<EventType>(event));
223 if(HasParent()) GetParent().ChildPublish<EventType>(event, id);
224 }
225
226 EventManager events;
227 std::vector<std::pair<Utilities::ID, std::string>> handlers;
228
229 //Children functions
230 public:
236 int AddChild(const Utilities::ID& gameObjectID);
237
242 void RemoveChild(int index);
243
249 GameObject& GetChild(int index) const;
250
255 uint GetChildCount() const;
256
261 bool HasParent() const { return !parent.IsNull(); }
262
267 GameObject& GetParent() const;
268
273 Scene& GetScene() const;
274
275 private:
280 void SetParent(const Utilities::ID& id);
281
283 std::vector<Utilities::ID> children;
284
285 //Component functions
286 private:
287 std::vector<std::unique_ptr<Component>> components;
288
289 public:
296 template <class T>
297 typename std::enable_if<std::is_base_of<Component,T>::value,T*>::type
298 GetComponent(bool log = true) {
299 //Find component
300 for (int i = 0; i < components.size(); i++) {
301 if (dynamic_cast<T*>(components[i].get())) {
302 T* component = (T*)components[i].get();
303 return component;
304 }
305 }
306 //Return null
307 if (log) Log::Error(std::format("No component of type \"{}\" found on object {}", typeid(T).name(), id.GetString()), true);
308 return nullptr;
309 }
310
316 template <class T>
317 typename std::enable_if<std::is_base_of<Component,T>::value, std::vector<T*> >::type
319 //Define vector
320 std::vector<T*> foundComponents;
321 //Find components
322 for (int i = 0; i < components.size(); i++) {
323 if (dynamic_cast<T*>(components[i].get())) {
324 T* component = (T*)components[i].get();
325 foundComponents.push_back(component);
326 }
327 }
328 //Return null
329 return foundComponents;
330 }
331
336 std::vector<Component*> GetAllComponents() const {
337 std::vector<Component*> vec;
338 for(auto& component : components) vec.push_back(component.get());
339 return vec;
340 }
341
347 template <class T>
348 typename std::enable_if<std::is_base_of<Component,T>::value, std::vector<T*> >::type
350 //Define vector
351 std::vector<T*> allComponents;
352 //Find components in this object:
353 std::vector<T*> current = GetAllComponents<T>();
354 allComponents.insert(allComponents.end(), current.begin(), current.end());
355 //Find components in each child object
356 for (int i = 0; i < children.size(); i++) {
357 std::vector<T*> childComp = GetChild(i).GetAllComponentsInChildren<T>();
358 allComponents.insert(allComponents.end(), childComp.begin(), childComp.end());
359 }
360 //Return components
361 return allComponents;
362 }
363
369 template <class T>
370 typename std::enable_if<std::is_base_of<Component,T>::value, T* >::type
371 AddComponent(T* component) {
372 if(!component) return nullptr;
373 //If unique check uniqueness
374 if (component->unique) {
375 if (GetComponent<T>(false) != nullptr) {
376 Log::Error(std::format("Object {} already has a component of type \"{}\", and this component requires to be unique", id.GetString(), typeid(T).name()), true);
377 return nullptr;
378 }
379 }
380 //Add to list
381 component->SetObject(*this, this->scene);
382 components.emplace_back(component);
383 if(isActive) component->Start();
384 return component;
385 }
386
391 template <class T>
392 typename std::enable_if<std::is_base_of<Component,T>::value, void >::type
394 //Find component
395 auto i = components.begin();
396 while (i != components.end()) {
397 if (dynamic_cast<T*>(*i)) {
398 //Delete component from memory
400 //Remove from list
401 i = components.erase(i);
402 }
403 else {
404 ++i;
405 }
406 }
407 }
408
414 template <class T>
415 typename std::enable_if<std::is_base_of<Component,T>::value, void >::type
416 RemoveComponent(T* component) {
417 //Find component
418 for (int i = 0; i < components.size(); i++) {
419 if (components[i].get() == component) {
420 //Remove from list
421 components.erase(components.begin() + i);
422 //Delete component from memory
423 delete component;
424 return;
425 }
426 }
427 Log::Error(std::format("No component of type \"{}\" found on object {}", typeid(T).name(), id.GetString()), true);
428 }
429 };
430
435 public:
442 TransformUpdateEvent(bool position = true, bool rotation = true, bool scale = true)
443 : position(position), rotation(rotation), scale(scale) {}
444 const std::string GetEventType() const override { return GetStaticEventType(); };
445 static const std::string GetStaticEventType() { return "TransformUpdateEvent"; }
446 bool position, rotation, scale;
447 };
448
449 #ifdef StevEngine_SHOW_WINDOW
453 class DrawEvent : public Event {
454 public:
460 const std::string GetEventType() const override { return GetStaticEventType(); };
461 static const std::string GetStaticEventType() { return "DrawEvent"; }
463 };
464 #endif
465
469 class DeactivateEvent : public Event {
470 public:
471 DeactivateEvent() {}
472 const std::string GetEventType() const override { return GetStaticEventType(); };
473 static const std::string GetStaticEventType() { return "DeactivateEvent"; }
474 };
475}
Wrapper for events from child objects.
Definition GameObject.hpp:21
const std::string GetEventType() const override
Get type identifier for this event.
Definition GameObject.hpp:25
const EventType & event
Original event.
Definition GameObject.hpp:24
const std::string GetEventType() const override
Get type identifier for this event.
Definition GameObject.hpp:472
DrawEvent(Utilities::Matrix4 transform)
Create draw event.
Definition GameObject.hpp:459
const std::string GetEventType() const override
Get type identifier for this event.
Definition GameObject.hpp:460
Utilities::Matrix4 transform
World transform matrix.
Definition GameObject.hpp:462
void Publish(const Event &event)
Publish event to subscribers.
Definition EventSystem.cpp:28
Base class for all engine events.
Definition EventSystem.hpp:12
Core game object class.
Definition GameObject.hpp:35
Utilities::Vector3 GetPosition() const
Get local position.
Definition GameObject.cpp:40
Utilities::Quaternion GetRotation() const
Get local rotation.
Definition GameObject.cpp:41
~GameObject()
Definition GameObject.cpp:160
Utilities::Stream Export(Utilities::StreamType type) const
Serialize object to a stream.
Definition GameObject.cpp:128
std::string name
Object name/label.
Definition GameObject.hpp:41
GameObject & GetChild(int index) const
Get child object.
Definition GameObject.cpp:100
Scene & GetScene() const
Get containing Scene.
Definition GameObject.cpp:109
std::enable_if< std::is_base_of< Component, T >::value, std::vector< T * > >::type GetAllComponents()
Get all components of specified type.
Definition GameObject.hpp:318
void Import(Utilities::Stream &stream)
Load object from serialized data.
Definition GameObject.cpp:144
void Unsubscribe(const std::string eventId, const Utilities::ID handlerId)
Unsubscribe from events.
Definition GameObject.hpp:211
std::vector< Component * > GetAllComponents() const
Get all components of any type.
Definition GameObject.hpp:336
Utilities::Quaternion GetWorldRotation()
Get world rotation.
Definition GameObject.cpp:69
GameObject(Utilities::ID id, std::string name, std::string scene)
Should never be called directly, use Scene::CreateObject.
Definition GameObject.cpp:85
std::enable_if< std::is_base_of< Component, T >::value, void >::type RemoveComponent(T *component)
Remove specific component instance.
Definition GameObject.hpp:416
std::enable_if< std::is_base_of< Component, T >::value, T * >::type AddComponent(T *component)
Add component to object.
Definition GameObject.hpp:371
Utilities::Vector3 GetWorldScale()
Get world scale.
Definition GameObject.cpp:76
void Publish(const EventType &event)
Publish an event.
Definition GameObject.hpp:201
void SetScale(Utilities::Vector3 scale, bool announce=true)
Set local scale.
Definition GameObject.cpp:51
void RemoveChild(int index)
Remove child at index.
Definition GameObject.cpp:96
Utilities::ID Subscribe(EventFunction< EventType > handler, bool allowFromChild=true)
Subscribe to object events.
Definition GameObject.hpp:189
Utilities::Vector3 GetScale() const
Get local scale.
Definition GameObject.cpp:42
void SetPosition(Utilities::Vector3 position, bool announce=true)
Set local position.
Definition GameObject.cpp:43
std::enable_if< std::is_base_of< Component, T >::value, T * >::type GetComponent(bool log=true)
Get component of specified type.
Definition GameObject.hpp:298
int AddChild(const Utilities::ID &gameObjectID)
Add child object.
Definition GameObject.cpp:90
GameObject & GetParent() const
Get parent object.
Definition GameObject.cpp:106
void SetRotation(Utilities::Quaternion rotation, bool announce=true)
Set local rotation.
Definition GameObject.cpp:47
void SetTransform(Utilities::Vector3 position, Utilities::Quaternion rotation, Utilities::Vector3 scale, bool announce=true)
Set full local transform.
Definition GameObject.cpp:55
bool HasParent() const
Check if object has a parent.
Definition GameObject.hpp:261
std::enable_if< std::is_base_of< Component, T >::value, std::vector< T * > >::type GetAllComponentsInChildren()
Get components of type from this object and all children.
Definition GameObject.hpp:349
Utilities::Vector3 GetWorldPosition()
Get world position.
Definition GameObject.cpp:61
uint GetChildCount() const
Get number of children.
Definition GameObject.cpp:103
Utilities::ID Id() const
Get object's unique ID.
Definition GameObject.hpp:47
std::enable_if< std::is_base_of< Component, T >::value, void >::type RemoveAllComponents()
Remove all components of specified type.
Definition GameObject.hpp:393
Container for game objects and scene state.
Definition Scene.hpp:21
TransformUpdateEvent(bool position=true, bool rotation=true, bool scale=true)
Create transform update event.
Definition GameObject.hpp:442
const std::string GetEventType() const override
Get type identifier for this event.
Definition GameObject.hpp:444
bool scale
Which transform components changed.
Definition GameObject.hpp:446
UUID-based unique identifier.
Definition ID.hpp:13
static ID empty
Null/empty ID value.
Definition ID.hpp:80
4x4 matrix for 3D transformations
Definition Matrix4.hpp:12
Quaternion for 3D rotations.
Definition Quaternion.hpp:19
Stream for serialization of data.
Definition Stream.hpp:20
3D vector class
Definition Vector3.hpp:19