engine/include/object.hpp

113 lines
2.4 KiB
C++
Raw Normal View History

2022-09-02 11:06:59 +00:00
#pragma once
2022-09-07 09:02:01 +00:00
#include "engine_api.h"
2022-09-02 23:02:09 +00:00
2022-11-30 00:46:03 +00:00
#include "log.hpp"
2022-11-30 00:46:03 +00:00
#include <glm/mat4x4.hpp>
#include <glm/gtc/quaternion.hpp>
2022-10-27 22:06:56 +00:00
2022-09-02 11:06:59 +00:00
#include <list>
#include <vector>
#include <string>
#include <memory>
2022-10-02 15:34:51 +00:00
namespace engine {
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
/* forward declarations */
class Scene;
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
class Component {
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
};
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
struct Transform {
// Scale, rotate (XYZ), translate
glm::vec3 position{ 0.0f };
glm::quat rotation{};
glm::vec3 scale{ 1.0f };
};
2022-10-27 16:58:30 +00:00
2022-11-30 00:46:03 +00:00
class Object {
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
public:
Object(const std::string& name, Object* parent, Scene* scene);
Object(const Object&) = delete;
Object& operator=(const Object&) = delete;
~Object();
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
/* methods */
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
Object* getChild(const std::string& name);
2022-10-06 10:30:44 +00:00
std::vector<Object*> getChildren();
2022-11-30 00:46:03 +00:00
Object* createChild(const std::string& name);
bool deleteChild(const std::string& name);
2022-09-02 11:06:59 +00:00
2022-10-06 10:30:44 +00:00
void printTree(int level = 0);
2022-09-02 11:06:59 +00:00
2022-10-06 10:30:44 +00:00
// Returns the component of type T
// Returns nullptr if the component is not found.
template<class T> T* getComponent();
template<class T> T* createComponent();
2022-11-30 00:46:03 +00:00
template<class T> bool deleteComponent();
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
/* public member variables */
2022-11-30 00:46:03 +00:00
const std::string name;
Object* const parent;
Scene* const scene;
2022-10-06 10:30:44 +00:00
Transform transform;
2022-09-02 11:06:59 +00:00
2022-10-06 10:30:44 +00:00
private:
2022-11-30 00:46:03 +00:00
static int s_next_id;
int m_id = s_next_id;
2022-09-02 11:06:59 +00:00
2022-11-30 00:46:03 +00:00
// If nullptr, this is the root object
2022-10-06 10:30:44 +00:00
std::list<std::unique_ptr<Object>> m_children{};
std::list<std::unique_ptr<Component>> m_components{};
2022-09-02 11:06:59 +00:00
2022-10-06 10:30:44 +00:00
};
2022-11-30 00:46:03 +00:00
/* implementation of template functions */
2022-10-06 10:30:44 +00:00
template<class T> T* Object::getComponent()
{
for (const auto& component : m_components) {
T* derived = dynamic_cast<T*>(component.get());
if (derived != nullptr) {
return derived;
}
2022-09-02 11:06:59 +00:00
}
2022-10-06 10:30:44 +00:00
return nullptr;
2022-09-02 11:06:59 +00:00
}
2022-10-06 10:30:44 +00:00
template <class T> T* Object::createComponent()
{
if (std::is_base_of<Component, T>::value == false) {
2022-11-30 00:46:03 +00:00
ERROR("Object::createComponent(): attempt to create a component with a non-component class");
return nullptr;
2022-10-06 10:30:44 +00:00
}
if (getComponent<T>() != nullptr) {
2022-11-30 00:46:03 +00:00
ERROR("Object::createComponent(): attempt to create a component that already exists on an object");
return nullptr;
2022-10-06 10:30:44 +00:00
}
m_components.emplace_back(std::make_unique<T>(this));
return dynamic_cast<T*>(m_components.back().get());
2022-09-02 11:06:59 +00:00
}
2022-10-06 10:30:44 +00:00
2022-11-30 00:46:03 +00:00
template<class T> bool Object::deleteComponent()
2022-10-06 10:30:44 +00:00
{
for (auto itr = m_components.begin(); itr != m_components.end(); ++itr) {
if (dynamic_cast<T*>((*itr).get()) != nullptr) {
m_components.erase(itr);
2022-11-30 00:46:03 +00:00
return true;
2022-10-06 10:30:44 +00:00
}
2022-09-02 11:06:59 +00:00
}
2022-11-30 00:46:03 +00:00
return false;
2022-09-02 11:06:59 +00:00
}
2022-10-06 10:30:44 +00:00
2022-10-27 22:06:56 +00:00
}