Skip to content

Instantly share code, notes, and snippets.

@paulfrische
Last active February 23, 2025 16:33
Show Gist options
  • Select an option

  • Save paulfrische/af8df4896cf7a94b068c3537eeaf2485 to your computer and use it in GitHub Desktop.

Select an option

Save paulfrische/af8df4896cf7a94b068c3537eeaf2485 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <memory>
#include <unordered_map>
class GameObject;
class Component
{
public:
virtual void OnSetup() {}
virtual void OnUpdate() {}
GameObject *object = nullptr; // is a raw pointer because `GameObject`s are designed to always outlive their components
};
class GameObject
{
public:
GameObject() {}
void Update()
{
for (const auto &[_, component] : components)
{
component->OnUpdate();
}
}
template <typename T> void AddComponent() noexcept
{
auto name = typeid(T).name();
if (components.contains(name))
{
return;
}
components[name] = std::make_shared<T>();
components[name]->object = this;
components[name]->OnSetup();
}
template <typename T> std::shared_ptr<T> GetComponent() noexcept
{
auto name = typeid(T).name();
if (!components.contains(name))
{
return nullptr;
}
return std::static_pointer_cast<T>(components[name]);
}
private:
std::unordered_map<const char *, std::shared_ptr<Component>> components;
};
struct Transform : public Component
{
float x = 0.0f;
float y = 0.0f;
float z = 0.0f;
};
struct Physics : public Component
{
std::shared_ptr<Transform> transform = nullptr;
void OnSetup() override { transform = object->GetComponent<Transform>(); }
void OnUpdate() override
{
std::cout << "update physics! transform->y = " << transform->y << "\n";
transform->y -= 10.0f;
}
};
int main()
{
GameObject obj;
GameObject obj2;
obj2.AddComponent<Transform>();
obj2.AddComponent<Physics>();
while (true)
{
obj.Update();
obj2.Update();
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment