SleakEngine
0.1.0
C++23 multi-backend game engine
Toggle main menu visibility
Loading...
Searching...
No Matches
GameObject.hpp
Go to the documentation of this file.
1
#ifndef _GAMEOBJECT_H_
2
#define _GAMEOBJECT_H_
3
4
#include "
Object.hpp
"
5
#include <
Core/Logger.hpp
>
6
#include <
ECS/Component.hpp
>
7
#include <
Utility/Container/List.hpp
>
8
#include <
Memory/RefPtr.hpp
>
9
#include <type_traits>
10
#include <string>
11
12
namespace
Sleak
{
13
namespace
Math
{
class
Vector3D
;};
14
class
SceneBase
;
15
/// Scene entity holding components and an optional parent/child transform
16
/// hierarchy. Scene owns the instance; destroy via Scene::DestroyObject().
17
///
18
/// A GameObject on its own does nothing. Behavior comes from the
19
/// components attached to it: a TransformComponent for placement, a
20
/// MeshComponent and MaterialComponent to be drawn, a ColliderComponent
21
/// and RigidbodyComponent to be simulated, and your own Component
22
/// subclasses for gameplay.
23
///
24
/// AddComponent<T>() constructs the component in place, forwarding
25
/// extra arguments to its constructor after the owner pointer. Only one
26
/// component of a given type is allowed per object: a second
27
/// AddComponent<T>() logs a warning and does nothing. GetComponent<T>()
28
/// resolves through `dynamic_cast`, so it also matches subclasses.
29
///
30
/// The scene that received the object through SceneBase::AddObject()
31
/// owns it. Never `delete` a GameObject. Use SceneBase::DestroyObject()
32
/// for deferred destruction, which is what you want while iterating, or
33
/// SceneBase::RemoveObject() for immediate destruction.
34
///
35
/// A parent owns every child that was not itself added to a scene, so a
36
/// hierarchy built with SetParent() (for example by ModelLoader) only
37
/// needs its root added. Deleting a parent deletes those children too.
38
///
39
/// Camera, Light, and its subclasses all derive from GameObject, so
40
/// they are added and found the same way as anything else.
41
///
42
/// @code{.cpp}
43
/// auto* crate = Sleak::GameObject::CreateCube(
44
/// Sleak::Math::Vector3D(0.0f, 1.0f, 0.0f));
45
/// crate->SetTag("Destructible");
46
///
47
/// crate->AddComponent<Sleak::MaterialComponent>(
48
/// Sleak::RefPtr<Sleak::Material>(new Sleak::Material()));
49
/// crate->AddComponent<Sleak::RigidbodyComponent>(
50
/// Sleak::BodyType::Dynamic);
51
///
52
/// if (auto* t = crate->GetComponent<Sleak::TransformComponent>()) {
53
/// t->SetScale(Sleak::Math::Vector3D(2.0f, 2.0f, 2.0f));
54
/// }
55
///
56
/// AddObject(crate); // the scene now owns it
57
/// @endcode
58
///
59
/// @see Component, SceneBase, TransformComponent, MeshComponent,
60
/// MaterialComponent, Camera
61
/// @ingroup scene
62
class
ENGINE_API
GameObject
:
public
Object
{
63
public
:
64
GameObject
(
const
std::string& name =
"GameObject"
)
65
:
Object
(name), m_isActive(true),
bIsInitialized
(false),
66
m_pendingDestroy(false), m_parent(nullptr) {}
67
68
~GameObject
()
override
;
69
70
/// Constructs and attaches a component of type T. Warns and no-ops if one already exists.
71
template
<
typename
T,
typename
... Args>
72
void
AddComponent
(Args&&... args) {
73
static_assert
(std::is_base_of<Component, T>::value,
"T must derive from Component!"
);
74
75
if
(
GetComponent<T>
() !=
nullptr
) {
76
SLEAK_WARN
(
"The component already exists!"
);
77
return
;
78
}
79
80
RefPtr<Component>
newComponent =
RefPtr<T>
(
new
T(
this
, std::forward<Args>(args)...));
81
if
(
bIsInitialized
) InitializeComponent(newComponent.
get
());
82
Components.add(std::move(newComponent));
83
}
84
85
/// Destroys and detaches the first component of type T, if present.
86
template
<
typename
T>
87
void
RemoveComponent
() {
88
static_assert
(std::is_base_of<Component, T>::value,
"T must derive from Component!"
);
89
90
for
(
size_t
i = 0; i < Components.GetSize(); ++i) {
91
if
(
dynamic_cast<
T*
>
(Components[i].get()) !=
nullptr
) {
92
Components[i]->OnDestroy();
93
Components.erase(i);
94
break
;
95
}
96
}
97
}
98
99
/// Finds the first attached component of type T, or nullptr.
100
template
<
typename
T>
101
T*
GetComponent
() {
102
static_assert
(std::is_base_of_v<Component, T>,
103
"T must derive from Component!"
);
104
105
for
(
size_t
i = 0; i < Components.GetSize(); ++i) {
106
Component
* rawPtr = Components[i].get();
107
if
(!rawPtr)
continue
;
108
109
T* component =
dynamic_cast<
T*
>
(rawPtr);
110
if
(component)
return
component;
111
}
112
113
return
nullptr
;
114
}
115
116
/// True if a component of type T is attached.
117
template
<
typename
T>
118
bool
HasComponent
() {
119
static_assert
(std::is_base_of_v<Component, T>,
120
"T must derive from Component!"
);
121
return
GetComponent<T>
() !=
nullptr
;
122
}
123
124
/// Initializes the object, components and children; repeats no-op.
125
virtual
void
Initialize();
126
bool
IsInitialized
()
const
{
return
bIsInitialized
; }
127
virtual
void
Update
(
float
deltaTime);
128
virtual
void
FixedUpdate(
float
fixedDeltaTime);
129
virtual
void
LateUpdate(
float
deltaTime);
130
131
/// Enables or disables the object, firing OnEnable/OnDisable on its components.
132
void
SetActive(
bool
active);
133
bool
IsActive
()
const
{
return
m_isActive; }
134
135
void
SetTag
(
const
std::string& tag) { m_tag = tag; }
136
const
std::string&
GetTag
()
const
{
return
m_tag; }
137
138
/// Reparents this object, updating both the old and new parent's child lists.
139
void
SetParent(
GameObject
* parent);
140
GameObject
*
GetParent
()
const
{
return
m_parent; }
141
const
List<GameObject*>
&
GetChildren
()
const
{
return
m_children; }
142
void
AddChild(
GameObject
* child);
143
void
RemoveChild(
GameObject
* child);
144
bool
HasParent
()
const
{
return
m_parent !=
nullptr
; }
145
bool
HasChildren
()
const
{
return
m_children.GetSize() > 0; }
146
/// True once a scene took ownership through SceneBase::AddObject().
147
bool
IsOwnedByScene
()
const
{
return
m_ownedByScene; }
148
149
virtual
bool
IsLight
()
const
{
return
false
; }
150
151
/// Flags the object for deferred destruction on the next scene pass.
152
void
MarkForDestroy
() { m_pendingDestroy =
true
; }
153
bool
IsPendingDestroy
()
const
{
return
m_pendingDestroy; }
154
155
/// Built-in primitive factories, mainly for prototyping and debug scenes.
156
static
GameObject
* CreatePlane(
Math::Vector3D
position,
int
width
= 100,
int
height
= 100);
157
static
GameObject
* CreateCube(
Math::Vector3D
position);
158
static
GameObject
* CreateSphere(
Math::Vector3D
position,
int
stack = 16,
int
slices = 16);
159
static
GameObject
* CreateCapsule(
Math::Vector3D
position,
int
segments = 16,
int
rings = 8,
float
height
= 1,
float
radius = 0.5);
160
static
GameObject
* CreateCylinder(
Math::Vector3D
position,
int
segments = 16,
float
height
= 1,
float
radius = 0.5);
161
static
GameObject
*
CreateTorus
(
Math::Vector3D
position,
int
segments = 16,
int
rings = 8,
float
innerRadius = 8,
float
outerRadius = 9);
162
163
protected
:
164
bool
bIsInitialized
;
165
166
private
:
167
bool
m_isActive;
168
bool
m_pendingDestroy;
169
bool
m_ownedByScene =
false
;
170
std::string m_tag =
"Untagged"
;
171
172
List<RefPtr<Component>
> Components;
173
174
// Hierarchy
175
GameObject
* m_parent;
176
List<GameObject*>
m_children;
177
178
/// Calls OnDestroy() on and drops every attached component.
179
void
DestroyComponents();
180
/// Initializes a component once, then enables it if active.
181
void
InitializeComponent(
Component
* component);
182
183
friend
class
SceneBase
;
184
};
185
}
186
187
#endif
// _GAMEOBJECT_H_
width
int width
Definition
Application.cpp:40
height
int height
Definition
Application.cpp:41
Component.hpp
List.hpp
Logger.hpp
SLEAK_WARN
#define SLEAK_WARN(...)
Definition
Logger.hpp:21
Object.hpp
RefPtr.hpp
Sleak::Component
Definition
Component.hpp:59
Sleak::GameObject
Definition
GameObject.hpp:62
Sleak::GameObject::HasComponent
bool HasComponent()
True if a component of type T is attached.
Definition
GameObject.hpp:118
Sleak::GameObject::GetParent
GameObject * GetParent() const
Definition
GameObject.hpp:140
Sleak::GameObject::AddComponent
void AddComponent(Args &&... args)
Constructs and attaches a component of type T. Warns and no-ops if one already exists.
Definition
GameObject.hpp:72
Sleak::GameObject::GetChildren
const List< GameObject * > & GetChildren() const
Definition
GameObject.hpp:141
Sleak::GameObject::HasParent
bool HasParent() const
Definition
GameObject.hpp:144
Sleak::GameObject::MarkForDestroy
void MarkForDestroy()
Flags the object for deferred destruction on the next scene pass.
Definition
GameObject.hpp:152
Sleak::GameObject::IsOwnedByScene
bool IsOwnedByScene() const
True once a scene took ownership through SceneBase::AddObject().
Definition
GameObject.hpp:147
Sleak::GameObject::IsActive
bool IsActive() const
Definition
GameObject.hpp:133
Sleak::GameObject::HasChildren
bool HasChildren() const
Definition
GameObject.hpp:145
Sleak::GameObject::IsPendingDestroy
bool IsPendingDestroy() const
Definition
GameObject.hpp:153
Sleak::GameObject::IsLight
virtual bool IsLight() const
Definition
GameObject.hpp:149
Sleak::GameObject::bIsInitialized
bool bIsInitialized
Definition
GameObject.hpp:164
Sleak::GameObject::GetComponent
T * GetComponent()
Finds the first attached component of type T, or nullptr.
Definition
GameObject.hpp:101
Sleak::GameObject::SetTag
void SetTag(const std::string &tag)
Definition
GameObject.hpp:135
Sleak::GameObject::GameObject
GameObject(const std::string &name="GameObject")
Definition
GameObject.hpp:64
Sleak::GameObject::CreateTorus
static GameObject * CreateTorus(Math::Vector3D position, int segments=16, int rings=8, float innerRadius=8, float outerRadius=9)
Sleak::GameObject::SceneBase
friend class SceneBase
Definition
GameObject.hpp:183
Sleak::GameObject::IsInitialized
bool IsInitialized() const
Definition
GameObject.hpp:126
Sleak::GameObject::GetTag
const std::string & GetTag() const
Definition
GameObject.hpp:136
Sleak::GameObject::RemoveComponent
void RemoveComponent()
Destroys and detaches the first component of type T, if present.
Definition
GameObject.hpp:87
Sleak::List
Implements a dynamic array-like list for storing and managing a collection of elements.
Definition
List.hpp:20
Sleak::Math::Vector3D
Definition
Vector.hpp:354
Sleak::Object::Object
Object(const std::string &name="Object")
Definition
Object.hpp:14
Sleak::RefPtr
Definition
RefPtr.hpp:62
Sleak::RefPtr::get
T * get() const
Definition
RefPtr.hpp:170
Sleak::SceneBase
Definition
SceneBase.hpp:72
Sleak::EventType::Update
@ Update
Definition
Event.hpp:26
Sleak::Math
Vectors, matrices, quaternions, colors, AABBs, and random helpers.
Definition
GameObject.hpp:13
Sleak
Root namespace for everything the engine exposes.
Definition
Camera.hpp:10
include
public
Core
GameObject.hpp
Generated on
for SleakEngine by
1.18.0