Monad Engine da02fba2
> Undercity Codex_
Loading...
Searching...
No Matches
Component.h
Go to the documentation of this file.
1/**
2 * @file Component.h
3 * @ingroup mnd_scene
4 * @brief Abstract base for all GameObject components and the COMPONENT macro.
5 *
6 * ## Entity-Component pattern
7 * A GameObject is a named scene node with a transform. Behaviour and
8 * rendering are added by attaching Component subclasses. Each component
9 * type gets a unique numeric ID at runtime so that typed lookup via
10 * GameObject::GetComponent<T>() works in O(n) without RTTI.
11 *
12 * ## Adding a new component type
13 * 1. Subclass Component.
14 * 2. Place the COMPONENT(MyComponent) macro at the top of the public section.
15 * 3. Implement Update(f32 deltaTime).
16 * 4. Attach via GameObject::AddComponent(new MyComponent(...)).
17 *
18 * @code
19 * class SpinComponent : public mnd::Component {
20 * COMPONENT(SpinComponent)
21 * public:
22 * void Update(mnd::f32 dt) override { m_owner->SetRotation(...); }
23 * };
24 * @endcode
25 *
26 * @see GameObject::AddComponent, GameObject::GetComponent, COMPONENT
27 */
28
29#pragma once
30
31#include "Types.h"
32#include "nlohmann/json.hpp"
33
34namespace mnd
35{
36class GameObject;
37
39{
40public:
41 virtual ~Component() = default;
42 virtual void LoadProperties(const nlohmann::json &json);
43 virtual void Update(f32 deltaTime) = 0;
44 virtual void Init();
45 virtual size_t GetTypeId() const = 0;
46
48
49 template<typename T>
50 static size_t StaticTypeId()
51 {
52 static size_t typeId = nextId++;
53 return typeId;
54 }
55
56protected:
57 GameObject *m_owner = nullptr;
58
59 friend class GameObject;
60
61private:
62 static size_t nextId;
63};
64
66{
67public:
68 virtual ~ComponentCreatorBase() = default;
69 virtual Component *CreateComponent() = 0;
70};
71
72template<typename T>
74{
75public:
76 Component *CreateComponent() override { return new T(); }
77};
78
80{
81public:
83
84 template<typename T>
85 void RegisterComponent(const std::string &name)
86 {
87 m_creators.emplace(name, std::make_unique<ComponentCreator<T>>());
88 }
89
90 Component *CreateComponent(const std::string &name)
91 {
92 auto it = m_creators.find(name);
93 if (it != m_creators.end())
94 {
95 return it->second->CreateComponent();
96 }
97
98 return nullptr;
99 }
100
101private:
102 std::unordered_map<std::string, std::unique_ptr<ComponentCreatorBase>> m_creators;
103};
104
105#define COMPONENT(ComponentClass) \
106public: \
107 static size_t TypeId() \
108 { \
109 return mnd::Component::StaticTypeId<ComponentClass>(); \
110 } \
111 size_t GetTypeId() const override \
112 { \
113 return TypeId(); \
114 } \
115 static void Register() \
116 { \
117 mnd::ComponentFactory::GetInstance().RegisterComponent<ComponentClass>(std::string(#ComponentClass)); \
118 }
119} // namespace mnd
Engine-wide primitive type aliases and GLM math imports.
virtual Component * CreateComponent()=0
virtual ~ComponentCreatorBase()=default
Component * CreateComponent() override
Definition Component.h:76
void RegisterComponent(const std::string &name)
Definition Component.h:85
static ComponentFactory & GetInstance()
Definition Component.cpp:17
Component * CreateComponent(const std::string &name)
Definition Component.h:90
virtual void Init()
Definition Component.cpp:10
GameObject * GetOwner()
Definition Component.cpp:12
GameObject * m_owner
Definition Component.h:57
virtual void Update(f32 deltaTime)=0
virtual ~Component()=default
static size_t StaticTypeId()
Definition Component.h:50
virtual void LoadProperties(const nlohmann::json &json)
Definition Component.cpp:8
virtual size_t GetTypeId() const =0
Node in the scene graph: a named transform that owns components and children.
Definition GameObject.h:91
float f32
32-bit IEEE float — the standard GL scalar type.
Definition Types.h:40