From fad4cb4c011b647a2f8211bb90cf7a45542679c8 Mon Sep 17 00:00:00 2001 From: auria Date: Thu, 18 Mar 2010 18:18:19 +0000 Subject: [PATCH] Updated menu singleton code, there was a bug in its logic (that had no consequence that i know but better fix it anyway) + some code style cleanup along the way git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5023 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/guiengine/screen.hpp | 39 ++-- src/states_screens/arenas_screen.cpp | 14 ++ src/states_screens/challenges.cpp | 187 +++++++++--------- src/states_screens/credits.cpp | 2 + src/states_screens/feature_unlocked.cpp | 3 + src/states_screens/grand_prix_over.cpp | 2 + src/states_screens/help_screen_1.cpp | 13 ++ src/states_screens/help_screen_2.cpp | 12 ++ src/states_screens/help_screen_3.cpp | 12 ++ src/states_screens/kart_selection.cpp | 2 + src/states_screens/main_menu_screen.cpp | 10 + src/states_screens/options_screen_av.cpp | 8 + src/states_screens/options_screen_input.cpp | 7 + src/states_screens/options_screen_players.cpp | 16 +- src/states_screens/options_screen_players.hpp | 3 + src/states_screens/race_setup_screen.cpp | 1 + src/states_screens/tracks_screen.cpp | 2 + 17 files changed, 219 insertions(+), 114 deletions(-) diff --git a/src/guiengine/screen.hpp b/src/guiengine/screen.hpp index faea38ffe..703d5fc8f 100644 --- a/src/guiengine/screen.hpp +++ b/src/guiengine/screen.hpp @@ -31,22 +31,27 @@ namespace GUIEngine { +#define DEFINE_SCREEN_SINGLETON( ClassName ) template<> ClassName* GUIEngine::ScreenSingleton< ClassName >::singleton = NULL + /** + * Declares a class to be a singleton. Normally, all screens will be singletons. + * Note that you need to use the 'DEFINE_SCREEN_SINGLETON' macro in a .cpp file to + * actually define the instance (as this can't be done in a .h) + */ template class ScreenSingleton { - // Weird code to work around C++ (making it easy to use) - // Used to create, get and delete singleton instance - static SCREEN* singletonOperate(bool deleteInstance=false) + static SCREEN* singleton; + + public: + + ~ScreenSingleton() + { + singleton = NULL; + } + + static SCREEN* getInstance() { - static SCREEN* singleton = NULL; - - if (deleteInstance && singleton != NULL) - { - singleton = NULL; - return NULL; - } - if (singleton == NULL) { singleton = new SCREEN(); @@ -56,18 +61,6 @@ namespace GUIEngine return singleton; } - public: - - ~ScreenSingleton() - { - singletonOperate(true); - } - - static SCREEN* getInstance() - { - return singletonOperate(); - } - }; void parseScreenFileDiv(irr::io::IrrXMLReader* xml, ptr_vector& append_to); diff --git a/src/states_screens/arenas_screen.cpp b/src/states_screens/arenas_screen.cpp index 1d8cd8a11..482b2dfcb 100644 --- a/src/states_screens/arenas_screen.cpp +++ b/src/states_screens/arenas_screen.cpp @@ -29,10 +29,15 @@ using namespace GUIEngine; using namespace irr::core; using namespace irr::video; +DEFINE_SCREEN_SINGLETON( ArenasScreen ); + +// ------------------------------------------------------------------------------------------------------ + ArenasScreen::ArenasScreen() : Screen("arenas.stkgui") { } +// ------------------------------------------------------------------------------------------------------ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) { @@ -64,6 +69,8 @@ void ArenasScreen::eventCallback(Widget* widget, const std::string& name, const } +// ------------------------------------------------------------------------------------------------------ + void ArenasScreen::init() { DynamicRibbonWidget* w = this->getWidget("tracks"); @@ -99,10 +106,14 @@ void ArenasScreen::init() w->setSelection(w->getItems()[0].m_code_name, 0, true); } +// ------------------------------------------------------------------------------------------------------ + void ArenasScreen::tearDown() { } +// ------------------------------------------------------------------------------------------------------ + void ArenasScreen::setFocusOnTrack(const std::string& trackName) { DynamicRibbonWidget* w = this->getWidget("tracks"); @@ -111,3 +122,6 @@ void ArenasScreen::setFocusOnTrack(const std::string& trackName) // FIXME: don't hardcode player 0? w->setSelection(trackName, 0, true); } + +// ------------------------------------------------------------------------------------------------------ + diff --git a/src/states_screens/challenges.cpp b/src/states_screens/challenges.cpp index e51786c02..b79ffbd1b 100644 --- a/src/states_screens/challenges.cpp +++ b/src/states_screens/challenges.cpp @@ -36,109 +36,120 @@ using irr::core::stringw; using irr::core::stringc; -namespace GUIEngine +using namespace GUIEngine; + +DEFINE_SCREEN_SINGLETON( ChallengesScreen ); + +// ------------------------------------------------------------------------------------------------------ + +ChallengesScreen::ChallengesScreen() : Screen("challenges.stkgui") { + +} + +// ------------------------------------------------------------------------------------------------------ + +void ChallengesScreen::onUpdate(float elapsed_time, irr::video::IVideoDriver*) +{ +} + +// ------------------------------------------------------------------------------------------------------ + +void ChallengesScreen::init() +{ + DynamicRibbonWidget* w = this->getWidget("challenges"); + assert( w != NULL ); - ChallengesScreen::ChallengesScreen() : Screen("challenges.stkgui") + // Re-build track list everytime (accounts for locking changes, etc.) + w->clearItems(); + + const std::vector& activeChallenges = unlock_manager->getActiveChallenges(); + const std::vector& solvedChallenges = unlock_manager->getUnlockedFeatures(); + const std::vector& lockedChallenges = unlock_manager->getLockedChallenges(); + + const int activeChallengeAmount = activeChallenges.size(); + const int solvedChallengeAmount = solvedChallenges.size(); + const int lockedChallengeAmount = lockedChallenges.size(); + + for (int n=0; naddItem(activeChallenges[n]->getName() + L"\n" + activeChallenges[n]->getChallengeDescription(), + activeChallenges[n]->getId(), "/gui/challenge.png"); + } + for (int n=0; naddItem(solvedChallenges[n]->getName() + L"\n" + solvedChallenges[n]->getChallengeDescription(), + solvedChallenges[n]->getId(), "/textures/cup_gold.png"); + } + for (int n=0; naddItem( _("Locked : solve active challenges to gain access to more!"), "locked", + "/gui/challenge.png", true); } - void ChallengesScreen::onUpdate(float elapsed_time, irr::video::IVideoDriver*) - { - } - void ChallengesScreen::init() + w->updateItemDisplay(); +} + +// ------------------------------------------------------------------------------------------------------ + +void ChallengesScreen::tearDown() +{ +} + +// ------------------------------------------------------------------------------------------------------ + +void ChallengesScreen::eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) +{ + if (name == "back") + { + StateManager::get()->escapePressed(); + } + else if (name == "challenges") { DynamicRibbonWidget* w = this->getWidget("challenges"); assert( w != NULL ); - // Re-build track list everytime (accounts for locking changes, etc.) - w->clearItems(); + // FIXME : don't hardcode player 0? + const int playerID = 0; + std::string selection = w->getSelectionIDString( playerID ); - const std::vector& activeChallenges = unlock_manager->getActiveChallenges(); - const std::vector& solvedChallenges = unlock_manager->getUnlockedFeatures(); - const std::vector& lockedChallenges = unlock_manager->getLockedChallenges(); - - const int activeChallengeAmount = activeChallenges.size(); - const int solvedChallengeAmount = solvedChallenges.size(); - const int lockedChallengeAmount = lockedChallenges.size(); - - for (int n=0; naddItem(activeChallenges[n]->getName() + L"\n" + activeChallenges[n]->getChallengeDescription(), - activeChallenges[n]->getId(), "/gui/challenge.png"); + unlock_manager->playLockSound(); } - for (int n=0; naddItem(solvedChallenges[n]->getName() + L"\n" + solvedChallenges[n]->getChallengeDescription(), - solvedChallenges[n]->getId(), "/textures/cup_gold.png"); - } - for (int n=0; naddItem( _("Locked : solve active challenges to gain access to more!"), "locked", - "/gui/challenge.png", true); - } - - - - w->updateItemDisplay(); - } - - void ChallengesScreen::tearDown() - { - } - - void ChallengesScreen::eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID) - { - if (name == "back") - { - StateManager::get()->escapePressed(); - } - else if (name == "challenges") - { - DynamicRibbonWidget* w = this->getWidget("challenges"); - assert( w != NULL ); - - // FIXME : don't hardcode player 0? - const int playerID = 0; - std::string selection = w->getSelectionIDString( playerID ); - - if (selection == "locked") - { - unlock_manager->playLockSound(); - } - else if (!selection.empty()) - { - //FIXME: simplify and centralize race start sequence!! + //FIXME: simplify and centralize race start sequence!! - // Use latest used device - InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice(); - - // Create player and associate player with device (FIXME: ask for player ident) - StateManager::get()->createActivePlayer( UserConfigParams::m_all_players.get(0), device ); - - // Set up race manager appropriately - race_manager->setNumLocalPlayers(1); - race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); - - // ASSIGN should make sure that only input from assigned devices is read. - input_manager->getDeviceList()->setAssignMode(ASSIGN); - - // Go straight to the race - StateManager::get()->enterGameState(); - - //FIXME: why do we need to invoke the network manager for local games?? - network_manager->initCharacterDataStructures(); - network_manager->setupPlayerKartInfo(); - - // Launch challenge - unlock_manager->getChallenge(selection)->setRace(); - race_manager->startNew(); - } + // Use latest used device + InputDevice* device = input_manager->getDeviceList()->getLatestUsedDevice(); + + // Create player and associate player with device (FIXME: ask for player ident) + StateManager::get()->createActivePlayer( UserConfigParams::m_all_players.get(0), device ); + + // Set up race manager appropriately + race_manager->setNumLocalPlayers(1); + race_manager->setLocalKartInfo(0, UserConfigParams::m_default_kart); + + // ASSIGN should make sure that only input from assigned devices is read. + input_manager->getDeviceList()->setAssignMode(ASSIGN); + + // Go straight to the race + StateManager::get()->enterGameState(); + + //FIXME: why do we need to invoke the network manager for local games?? + network_manager->initCharacterDataStructures(); + network_manager->setupPlayerKartInfo(); + + // Launch challenge + unlock_manager->getChallenge(selection)->setRace(); + race_manager->startNew(); } } - -} // end namespace +} + +// ------------------------------------------------------------------------------------------------------ + diff --git a/src/states_screens/credits.cpp b/src/states_screens/credits.cpp index ac2dc2bee..a2f4930f2 100644 --- a/src/states_screens/credits.cpp +++ b/src/states_screens/credits.cpp @@ -29,6 +29,8 @@ using irr::core::stringc; #include "guiengine/engine.hpp" #include "io/file_manager.hpp" +DEFINE_SCREEN_SINGLETON( GUIEngine::CreditsScreen ); + namespace GUIEngine { diff --git a/src/states_screens/feature_unlocked.cpp b/src/states_screens/feature_unlocked.cpp index c93fa567c..5d4042e7a 100644 --- a/src/states_screens/feature_unlocked.cpp +++ b/src/states_screens/feature_unlocked.cpp @@ -20,6 +20,9 @@ using namespace irr::core; using namespace irr::gui; using namespace irr::video; + +DEFINE_SCREEN_SINGLETON( FeatureUnlockedCutScene ); + // ------------------------------------------------------------------------------------- FeatureUnlockedCutScene::FeatureUnlockedCutScene() : Screen("feature_unlocked.stkgui") diff --git a/src/states_screens/grand_prix_over.cpp b/src/states_screens/grand_prix_over.cpp index a227cdcda..cbdc3ecd8 100644 --- a/src/states_screens/grand_prix_over.cpp +++ b/src/states_screens/grand_prix_over.cpp @@ -25,6 +25,8 @@ const float INITIAL_Y = -3.0f; const float INITIAL_PODIUM_Y = -3.6f; const float PODIUM_HEIGHT[3] = { 0.325f, 0.5f, 0.15f }; +DEFINE_SCREEN_SINGLETON( GrandPrixOver ); + // ------------------------------------------------------------------------------------- GrandPrixOver::GrandPrixOver() : Screen("grand_prix_over.stkgui") diff --git a/src/states_screens/help_screen_1.cpp b/src/states_screens/help_screen_1.cpp index c4f11e31c..82623338e 100644 --- a/src/states_screens/help_screen_1.cpp +++ b/src/states_screens/help_screen_1.cpp @@ -21,12 +21,19 @@ #include "guiengine/widget.hpp" #include "states_screens/state_manager.hpp" + using namespace GUIEngine; +DEFINE_SCREEN_SINGLETON( HelpScreen1 ); + +// ------------------------------------------------------------------------------------------------------ + HelpScreen1::HelpScreen1() : Screen("help1.stkgui") { } +// ------------------------------------------------------------------------------------------------------ + void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "category") @@ -44,6 +51,8 @@ void HelpScreen1::eventCallback(Widget* widget, const std::string& name, const i } } +// ------------------------------------------------------------------------------------------------------ + void HelpScreen1::init() { RibbonWidget* w = this->getWidget("category"); @@ -51,6 +60,10 @@ void HelpScreen1::init() if (w != NULL) w->select( "page1", GUI_PLAYER_ID ); } +// ------------------------------------------------------------------------------------------------------ + void HelpScreen1::tearDown() { } + +// ------------------------------------------------------------------------------------------------------ diff --git a/src/states_screens/help_screen_2.cpp b/src/states_screens/help_screen_2.cpp index ebb9dbed4..b153835fc 100644 --- a/src/states_screens/help_screen_2.cpp +++ b/src/states_screens/help_screen_2.cpp @@ -21,12 +21,18 @@ #include "guiengine/widget.hpp" #include "states_screens/state_manager.hpp" + using namespace GUIEngine; +DEFINE_SCREEN_SINGLETON( HelpScreen2 ); + +// ------------------------------------------------------------------------------------------------------ + HelpScreen2::HelpScreen2() : Screen("help2.stkgui") { } +// ------------------------------------------------------------------------------------------------------ void HelpScreen2::eventCallback(Widget* widget, const std::string& name, const int playerID) { @@ -44,6 +50,8 @@ void HelpScreen2::eventCallback(Widget* widget, const std::string& name, const i } } +// ------------------------------------------------------------------------------------------------------ + void HelpScreen2::init() { RibbonWidget* w = this->getWidget("category"); @@ -51,6 +59,10 @@ void HelpScreen2::init() if (w != NULL) w->select( "page2", GUI_PLAYER_ID ); } +// ------------------------------------------------------------------------------------------------------ + void HelpScreen2::tearDown() { } + +// ------------------------------------------------------------------------------------------------------ diff --git a/src/states_screens/help_screen_3.cpp b/src/states_screens/help_screen_3.cpp index c4767ddb4..724122fbf 100644 --- a/src/states_screens/help_screen_3.cpp +++ b/src/states_screens/help_screen_3.cpp @@ -21,12 +21,18 @@ #include "guiengine/widget.hpp" #include "states_screens/state_manager.hpp" + using namespace GUIEngine; +DEFINE_SCREEN_SINGLETON( HelpScreen3 ); + +// ------------------------------------------------------------------------------------------------------ + HelpScreen3::HelpScreen3() : Screen("help3.stkgui") { } +// ------------------------------------------------------------------------------------------------------ void HelpScreen3::eventCallback(Widget* widget, const std::string& name, const int playerID) { @@ -44,6 +50,8 @@ void HelpScreen3::eventCallback(Widget* widget, const std::string& name, const i } } +// ------------------------------------------------------------------------------------------------------ + void HelpScreen3::init() { RibbonWidget* w = this->getWidget("category"); @@ -51,6 +59,10 @@ void HelpScreen3::init() if (w != NULL) w->select( "page3", GUI_PLAYER_ID ); } +// ------------------------------------------------------------------------------------------------------ + void HelpScreen3::tearDown() { } + +// ------------------------------------------------------------------------------------------------------ diff --git a/src/states_screens/kart_selection.cpp b/src/states_screens/kart_selection.cpp index 1c8b80adf..374b316b8 100644 --- a/src/states_screens/kart_selection.cpp +++ b/src/states_screens/kart_selection.cpp @@ -50,6 +50,8 @@ const char* RANDOM_KART_ID = "randomkart"; const char* ALL_KART_GROUPS_ID = "all"; const char* ID_DONT_USE = "x"; +DEFINE_SCREEN_SINGLETON( KartSelectionScreen ); + class PlayerKartWidget; /** Currently, navigation for multiple players at the same time is implemented in diff --git a/src/states_screens/main_menu_screen.cpp b/src/states_screens/main_menu_screen.cpp index d23a26935..aece6c50d 100644 --- a/src/states_screens/main_menu_screen.cpp +++ b/src/states_screens/main_menu_screen.cpp @@ -39,10 +39,15 @@ using namespace GUIEngine; +DEFINE_SCREEN_SINGLETON( MainMenuScreen ); + +// ------------------------------------------------------------------------------------------------------ + MainMenuScreen::MainMenuScreen() : Screen("main.stkgui") { } +// ------------------------------------------------------------------------------------------------------ void MainMenuScreen::init() { @@ -52,10 +57,14 @@ void MainMenuScreen::init() input_manager->setMasterPlayerOnly(false); } +// ------------------------------------------------------------------------------------------------------ + void MainMenuScreen::tearDown() { } +// ------------------------------------------------------------------------------------------------------ + void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, const int playerID) { RibbonWidget* ribbon = dynamic_cast(widget); @@ -121,3 +130,4 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, cons } +// ------------------------------------------------------------------------------------------------------ diff --git a/src/states_screens/options_screen_av.cpp b/src/states_screens/options_screen_av.cpp index d1a005547..b70724ca0 100644 --- a/src/states_screens/options_screen_av.cpp +++ b/src/states_screens/options_screen_av.cpp @@ -33,11 +33,16 @@ using namespace GUIEngine; +DEFINE_SCREEN_SINGLETON( OptionsScreenAV ); + +// ----------------------------------------------------------------------------- OptionsScreenAV::OptionsScreenAV() : Screen("options_av.stkgui") { } + // ----------------------------------------------------------------------------- + void OptionsScreenAV::init() { RibbonWidget* ribbon = this->getWidget("options_choice"); @@ -132,6 +137,7 @@ void OptionsScreenAV::init() } // ----------------------------------------------------------------------------- + void OptionsScreenAV::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "options_choice") @@ -219,7 +225,9 @@ void OptionsScreenAV::eventCallback(Widget* widget, const std::string& name, con } // ----------------------------------------------------------------------------- + void OptionsScreenAV::tearDown() { } +// ----------------------------------------------------------------------------- diff --git a/src/states_screens/options_screen_input.cpp b/src/states_screens/options_screen_input.cpp index c358b810b..147b84a1a 100644 --- a/src/states_screens/options_screen_input.cpp +++ b/src/states_screens/options_screen_input.cpp @@ -36,10 +36,16 @@ using namespace GUIEngine; +DEFINE_SCREEN_SINGLETON( OptionsScreenInput ); + +// ----------------------------------------------------------------------------- + OptionsScreenInput::OptionsScreenInput() : Screen("options_input.stkgui") { } + // ----------------------------------------------------------------------------- + void OptionsScreenInput::updateInputButtons(DeviceConfig* config) { @@ -288,6 +294,7 @@ void OptionsScreenInput::rebuildDeviceList() } // ----------------------------------------------------------------------------- + static PlayerAction binding_to_set; static std::string binding_to_set_button; diff --git a/src/states_screens/options_screen_players.cpp b/src/states_screens/options_screen_players.cpp index 323d48d9f..95b7a7195 100644 --- a/src/states_screens/options_screen_players.cpp +++ b/src/states_screens/options_screen_players.cpp @@ -37,10 +37,16 @@ using namespace GUIEngine; using namespace irr::core; using namespace irr::gui; +DEFINE_SCREEN_SINGLETON( OptionsScreenPlayers ); + +// ----------------------------------------------------------------------------- + OptionsScreenPlayers::OptionsScreenPlayers() : Screen("options_players.stkgui") { } + // ----------------------------------------------------------------------------- + void OptionsScreenPlayers::init() { RibbonWidget* ribbon = this->getWidget("options_choice"); @@ -56,9 +62,8 @@ void OptionsScreenPlayers::init() } } -/** - * Adds a new player (if 'player' is NULL) or renames an existing player (if 'player' is not NULL) - */ +// ----------------------------------------------------------------------------- + void OptionsScreenPlayers::gotNewPlayerName(const stringw& newName, PlayerProfile* player) { stringc newNameC( newName ); @@ -88,6 +93,8 @@ void OptionsScreenPlayers::gotNewPlayerName(const stringw& newName, PlayerProfil // TODO : need to re-save user config here? } +// ----------------------------------------------------------------------------- + void OptionsScreenPlayers::deletePlayer(PlayerProfile* player) { UserConfigParams::m_all_players.erase(player); @@ -108,11 +115,13 @@ void OptionsScreenPlayers::deletePlayer(PlayerProfile* player) // ----------------------------------------------------------------------------- + void OptionsScreenPlayers::tearDown() { } // ----------------------------------------------------------------------------- + void OptionsScreenPlayers::eventCallback(Widget* widget, const std::string& name, const int playerID) { if (name == "options_choice") @@ -151,3 +160,4 @@ void OptionsScreenPlayers::eventCallback(Widget* widget, const std::string& name } +// ----------------------------------------------------------------------------- diff --git a/src/states_screens/options_screen_players.hpp b/src/states_screens/options_screen_players.hpp index 4b64557f7..a5c718024 100644 --- a/src/states_screens/options_screen_players.hpp +++ b/src/states_screens/options_screen_players.hpp @@ -38,6 +38,9 @@ public: void eventCallback(GUIEngine::Widget* widget, const std::string& name, const int playerID); + /** + * Adds a new player (if 'player' is NULL) or renames an existing player (if 'player' is not NULL) + */ void gotNewPlayerName(const irr::core::stringw& newName, PlayerProfile* player=NULL); void deletePlayer(PlayerProfile* player); diff --git a/src/states_screens/race_setup_screen.cpp b/src/states_screens/race_setup_screen.cpp index 737e27c1a..421fb4213 100644 --- a/src/states_screens/race_setup_screen.cpp +++ b/src/states_screens/race_setup_screen.cpp @@ -30,6 +30,7 @@ using namespace GUIEngine; +DEFINE_SCREEN_SINGLETON( RaceSetupScreen ); class GameModeRibbonListener : public DynamicRibbonHoverListener { diff --git a/src/states_screens/tracks_screen.cpp b/src/states_screens/tracks_screen.cpp index 7eae6e43a..1696e76d5 100644 --- a/src/states_screens/tracks_screen.cpp +++ b/src/states_screens/tracks_screen.cpp @@ -34,6 +34,8 @@ using namespace irr::video; const char* ALL_TRACK_GROUPS_ID = "all"; +DEFINE_SCREEN_SINGLETON( TracksScreen ); + // ----------------------------------------------------------------------------------------------- TracksScreen::TracksScreen() : Screen("tracks.stkgui")