Dawn/src/dawn/scene/SceneItem.hpp

117 lines
3.6 KiB
C++

// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "SceneItemComponent.hpp"
#include "display/Transform.hpp"
#include "event/Event.hpp"
namespace Dawn {
typedef int32_t sceneitemid_t;
class Scene;
class SceneItem {
private:
std::vector<std::shared_ptr<SceneItemComponent>> components;
public:
Scene &scene;
sceneitemid_t id;
Transform transform;
/**
* Constructor for a SceneItem. Scene Items should only be called and
* initialized by the scene itself.
*
* @param scene Weak pointer to the Scene that this SceneItem belongs to.
* @param id Scene Item ID that the Scene assigned this SceneItem.
*/
SceneItem(Scene &scene, sceneitemid_t id);
/**
* Called by the Scene the frame after we were constructed so we can begin
* existing.
*/
void init();
/**
* Adds a component to this scene item. Components will only have their
* init methods invoked on the first frame we enter the scene. If you add
* a component to this item after this time you will either need to try
* manually invoking its' init method, or ensure the component is aware of
* the entire SceneItem lifecycle and listen for added callbacks.
*
* @tparam T Type of component being added to this scene item.
* @return A shared pointer to the newly added component.
*/
template<class T>
std::shared_ptr<T> addComponent() {
auto component = std::make_shared<T>(*this);
this->components.push_back(component);
return component;
}
/**
* Returns a component attached to this SceneItem. This method will return
* either a shared pointer to the component, or nullptr if the item does
* not have the queried component.
*
* @tparam T Type of component to be fetched.
* @return A shared pointer to the component, or nullptr if not found.
*/
template<class T>
std::shared_ptr<T> getComponent() {
auto it = this->components.begin();
while(it != this->components.end()) {
auto castedAs = std::dynamic_pointer_cast<T>(*it);
if(castedAs != nullptr) return castedAs;
++it;
}
return nullptr;
}
/**
* Finds a (direct) child of this component that has a matching component.
*
* @tparam T Component to find child of.
* @return Pointer to the child, or nullptr if not found.
*/
template<class T>
std::shared_ptr<T> findChild() {
auto it = this->transform.children.begin();
while(it != this->transform.children.end()) {
auto child = (*it)->item.getComponent<T>();
if(child != nullptr) return child;
++it;
}
return nullptr;
}
/**
* Finds all (direct) children of this component that match the queried
* component.
*
* @tparam T Component to find children for.
* @return Array of pointers to matching children.
*/
template<class T>
std::vector<std::shared_ptr<T>> findChildren() {
auto it = this->transform.children.begin();
std::vector<std::shared_ptr<T>> children;
while(it != this->transform.children.end()) {
auto child = (*it)->item.getComponent<T>();
if(child != nullptr) children.push_back(child);
++it;
}
return children;
}
/**
* Destroy this SceneItem.
*/
~SceneItem();
};
}