// Copyright (c) 2022 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "event/Event.hpp" #include "asset/Asset.hpp" #include "scene/debug/SceneDebugLine.hpp" namespace Dawn { class DawnGame; class RenderPipeline; class SceneItem; class SceneItemComponent; typedef int32_t sceneitemid_t; template T * _sceneForwardGetComponent(SceneItem *item); class Scene { private: sceneitemid_t nextId; std::map items; std::map itemsNotInitialized; public: DawnGame *game; Event<> eventSceneUpdate; Event<> eventSceneUnpausedUpdate; /** * Construct a new Scene instance. * * @param game Reference to the game that this scene belongs to. */ Scene(DawnGame *game); /** * Perform a one frame synchronous tick on the current scene. This may * change in future to be more event-like. */ void update(); /** * Create a Scene Item object and add to the current scene. * * @return A shared pointer to the created SceneItem. */ template T * createSceneItemOfType() { sceneitemid_t id = this->nextId++; auto item = new T(this, id); assertNotNull(item); this->itemsNotInitialized[id] = item; return item; } /** * Create a Scene Item object and add to the current scene. * * @return A shared pointer to the created SceneItem. */ SceneItem * createSceneItem(); /** * Returns the required assets for this scene. Assets required are meant * to be referenced back to the loader so that special loading actions can * be performed against them. * * @return List of assets required by this scene. */ virtual std::vector getRequiredAssets() = 0; /** * Method to begin the actual staging of the scene, typically called after * the scene has finished loading. */ virtual void stage() = 0; /** * Finds an existing component on the scene (Root Level Only) that has a * component matching the given component type. Returns nullptr if no item * with the specified component could be found. * * @tparam Component type to look for. * @return Pointer to the found component (and by extension the item). */ template T * findComponent() { auto it = this->itemsNotInitialized.begin(); while(it != this->itemsNotInitialized.end()) { auto component = _sceneForwardGetComponent(it->second); if(component != nullptr) return component; ++it; } auto it2 = this->items.begin(); while(it2 != this->items.end()) { auto component = _sceneForwardGetComponent(it2->second); if(component != nullptr) return component; ++it2; } return nullptr; } /** * Finds all exisitng components on the scene (Root Level Only) that has a * matching component of the given component type. * * @tparam Component type to look for. * @return List of matching compnoents. */ template std::vector findComponents() { std::vector components; auto it = this->itemsNotInitialized.begin(); while(it != this->itemsNotInitialized.end()) { auto component = _sceneForwardGetComponent(it->second); if(component != nullptr) components.push_back(component); ++it; } auto it2 = this->items.begin(); while(it2 != this->items.end()) { auto component = _sceneForwardGetComponent(it2->second); if(component != nullptr) components.push_back(component); ++it2; } return components; } // Scene debugging functions #if DAWN_DEBUG_BUILD std::vector debugLines; void debugLine(struct SceneDebugLine line); void debugCube(struct SceneDebugCube cube); void debugOrigin(); void debugGrid(); #endif /** * Destroys a previously initialized Scene. */ ~Scene(); friend class RenderPipeline; }; }