// Copyright (c) 2022 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "asset/Asset.hpp" #include "display/shader/ShaderManager.hpp" #include "scene/debug/SceneDebugLine.hpp" #include "physics/ScenePhysicsManager.hpp" #include "state/StateEvent.hpp" #include "state/StateOwner.hpp" namespace Dawn { class DawnGame; class RenderPipeline; class SceneItem; class SceneItemComponent; typedef int32_t sceneitemid_t; template std::shared_ptr _sceneForwardGetComponent(std::shared_ptr item); template std::vector> _sceneForwardGetComponents( std::shared_ptr item ); class Scene : public StateOwner, public std::enable_shared_from_this { private: sceneitemid_t nextId; std::map> items; std::map> itemsNotInitialized; public: std::weak_ptr game; ScenePhysicsManager *physics; StateEvent eventSceneUpdate; StateEvent eventSceneUnpausedUpdate; /** * Construct a new Scene instance. * * @param game Reference to the game that this scene belongs to. */ Scene(std::weak_ptr 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 std::shared_ptr createSceneItemOfType() { sceneitemid_t id = this->nextId++; auto item = std::make_shared(weak_from_this(), id); assertNotNull(item, "Failed to create SceneItem (Memory Filled?)"); 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. */ std::shared_ptr 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 std::shared_ptr 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; } /** * Destroys a previously initialized Scene. */ ~Scene(); friend class RenderPipeline; }; }