// 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 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(); /** * Called by the Scene when cleanup needs to occur but before anything in * the scene has been disposed. */ void destroy(); /** * 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 T * addComponent() { auto component = new T(this); assertNotNull(component); 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 T * getComponent() { auto it = this->components.begin(); while(it != this->components.end()) { T *castedAs = dynamic_cast(*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 T * findChild() { auto it = this->transform.children.begin(); while(it != this->transform.children.end()) { auto child = (*it)->item->getComponent(); 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 std::vector findChildren() { auto it = this->transform.children.begin(); std::vector children; while(it != this->transform.children.end()) { auto child = (*it)->item->getComponent(); if(child != nullptr) children.push_back(child); ++it; } return children; } /** * Destroy this SceneItem. */ ~SceneItem(); }; }