// Copyright (c) 2023 Dominic Masters // // This software is released under the MIT License. // https://opensource.org/licenses/MIT #pragma once #include "game/Game.hpp" #include "scene/SceneItem.hpp" #include "event/Event.hpp" #include "time/event/IntervalEvent.hpp" #include "time/event/TimeoutEvent.hpp" namespace Dawn { struct IntervalData { float_t frequency; float_t nextInvoke; }; class Scene final : public std::enable_shared_from_this { private: std::weak_ptr game; const std::function sceneInitializer; std::vector> sceneItems; std::vector> sceneItemsToRemove; bool_t paused = false; bool_t hasInitialized = false; public: Event onUnpausedUpdate; Event onPausedUpdate; TimeoutEvent onTimeout; IntervalEvent onInterval; /** * Returns the initial scene for the game. * * @return Initial scene function. */ static const std::function getInitialScene(); /** * Constructs a scene object. * * @param game Game that initialized this scene. */ Scene( const std::weak_ptr game, const std::function sceneInitializer ); /** * Stages all of the scene items on the scene. */ void stage(); /** * Called by the game every frame that the scene is set as the currently * active scene. This may not be sequential, for example a scene can be * active, then switched to a different scene temporarily, and then can be * switched back to the active one. */ void update(); /** * Returns a copy of the game instance that this scene belongs to. * * @return Shared pointer to the game instance. */ std::shared_ptr getGame(); /** * Creates a scene item that belongs to this scene. * * @return Pointer to the new scene item. */ std::shared_ptr createSceneItem(); /** * Removes a scene item from the scene. This remove will happen at the * start of the next scene update. * * @param item Scene item to remove. */ void removeItem(const std::shared_ptr item); /** * Returns a list of scene components that match the given type. * * @return List of scene components matching the type. */ template std::vector> findComponents() { std::vector> components; for(auto item : sceneItems) { auto component = item->getComponent(); if(component) components.push_back(component); } return components; } /** * Destroys the scene object and cleans up all of its children. */ virtual ~Scene(); }; }