#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2013 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_GAME_STATES_SCENEGRAPHGAMESTATE_H #define NUCLEX_GAME_STATES_SCENEGRAPHGAMESTATE_H #include "Nuclex/Game/Config.h" #include "GameState.h" namespace Nuclex { namespace Game { namespace States { // ------------------------------------------------------------------------------------------- // /// Game state for games using a scene graph /// /// /// This class translates the Entered()/Exiting() and Revealed()/Hiding() methods /// into something that is a better match for games using a retained rendering system, /// for example a scene graph, where the game state is not directly responsible for /// drawing to the screen, but manipulates nodes in a scene graph instead. /// /// /// A scene graph game state can be in 3 states. To go from the first to the last /// state or back, it has to go over the middle state. /// /// /// /// Created /// /// An instance of the game state has been created, but it has not built /// its scene nodes yet. Scene states are typically in this state if you store /// them in a repository, allowing for minimal resource usage (as no models and /// textures that would be part of the scene nodes are loaded). /// /// /// /// Prepared /// /// In this state, the scene nodes have been created but have not been attached /// to the game's scene graph yet. The game state is in this state when it has /// been obscured by another state (eg. a menu sitting on top of it), allowing /// it to be quickly restored to working oder. /// /// /// /// Attached /// /// The game state has attached its scene nodes to the game's scene graph and is /// actively updating these nodes. /// /// /// /// class SceneGraphGameState : public GameState { /// Initializes a new scene graph game state public: NUCLEX_GAME_API SceneGraphGameState(); /// Destroys the game state public: NUCLEX_GAME_API virtual ~SceneGraphGameState(); /// Notifies the game state that it has been obscured by another state /// /// This happens when another game state has been pushed on top of this state. A typical /// scenario would be if you leave your game's main menu on the state stack during /// the whole game, as soon as the game play state is entered, it would always draw over /// your main menu, thus the main menu should no longer bother drawing (or even actively /// remove its menu items from the game's GUI). /// public: void Hiding() { if(this->areSceneNodesCreated) { if(this->areSceneNodesAdded) { DetachSceneNodes(); this->areSceneNodesAdded = false; } } } /// Notifies the game state that it is no longer obscured /// /// This notification will be issued when the game state was obscured by another state /// sitting on top of it but that state has now been removed. If the revealed state /// was the game's main menu, for example, it should now resume drawing or perhaps /// re-add the menu items to the game's GUI in case it removed them when it was /// first obscured. /// public: void Revealed() { if(this->areSceneNodesCreated) { if(!this->areSceneNodesAdded) { AttachSceneNodes(); this->areSceneNodesAdded = true; } } } /// Notifies the game state it is about to be exited /// /// /// This happens when the game state is completely removed from the game state manager. /// Depending on your game's design, the state may be kept somewhere (presumably some /// state repository that's responsible for creating an storing states) or it may be /// deleted immediately following its removal from the game state manager. /// /// /// Upon receiving this notification, the game state should remove any nodes it has /// added to the game's scene graph, disconnect itself from input callbacks and so /// on. You may even want to destroy memory-intensive resources if the game state may /// be kept alive in your game. /// /// public: void Exiting() { if(this->areSceneNodesCreated) { if(this->areSceneNodesAdded) { DetachSceneNodes(); this->areSceneNodesAdded = false; } DestroySceneNodes(); this->areSceneNodesCreated = false; } } /// Notifies the game state that it has been entered /// /// This call allows the game state to add any nodes it requires to the game's scene /// graph or to connect to the callbacks of an input manager, etc. /// public: void Entered() { if(!this->areSceneNodesCreated) { CreateSceneNodes(); this->areSceneNodesCreated = true; if(!this->areSceneNodesAdded) { AttachSceneNodes(); this->areSceneNodesAdded = true; } } } /// Called when the state should create its scene nodes protected: virtual void CreateSceneNodes() {} /// Called when the state should destroy its scene nodes protected: virtual void DestroySceneNodes() {} /// Called when the state should add its nodes to the scene graph protected: virtual void AttachSceneNodes() {} /// Called when the state should remove its nodes from the scene graph protected: virtual void DetachSceneNodes() {} /// /// Whether the game state has currently added its contents to the scene graph /// private: bool areSceneNodesAdded; /// /// Whether the game state currently created its scene nodes /// private: bool areSceneNodesCreated; }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Game::States #endif // NUCLEX_GAME_STATES_SCENEGRAPHGAMESTATE_H