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
This commit is contained in:
auria 2010-03-18 18:18:19 +00:00
parent 6fd2feada7
commit fad4cb4c01
17 changed files with 219 additions and 114 deletions

View File

@ -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<typename SCREEN>
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<Widget>& append_to);

View File

@ -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<DynamicRibbonWidget>("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<DynamicRibbonWidget>("tracks");
@ -111,3 +122,6 @@ void ArenasScreen::setFocusOnTrack(const std::string& trackName)
// FIXME: don't hardcode player 0?
w->setSelection(trackName, 0, true);
}
// ------------------------------------------------------------------------------------------------------

View File

@ -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<DynamicRibbonWidget>("challenges");
assert( w != NULL );
ChallengesScreen::ChallengesScreen() : Screen("challenges.stkgui")
// Re-build track list everytime (accounts for locking changes, etc.)
w->clearItems();
const std::vector<const Challenge*>& activeChallenges = unlock_manager->getActiveChallenges();
const std::vector<const Challenge*>& solvedChallenges = unlock_manager->getUnlockedFeatures();
const std::vector<const Challenge*>& lockedChallenges = unlock_manager->getLockedChallenges();
const int activeChallengeAmount = activeChallenges.size();
const int solvedChallengeAmount = solvedChallenges.size();
const int lockedChallengeAmount = lockedChallenges.size();
for (int n=0; n<activeChallengeAmount; n++)
{
w->addItem(activeChallenges[n]->getName() + L"\n" + activeChallenges[n]->getChallengeDescription(),
activeChallenges[n]->getId(), "/gui/challenge.png");
}
for (int n=0; n<solvedChallengeAmount; n++)
{
// TODO : add bronze/silver/gold difficulties to challenges
w->addItem(solvedChallenges[n]->getName() + L"\n" + solvedChallenges[n]->getChallengeDescription(),
solvedChallenges[n]->getId(), "/textures/cup_gold.png");
}
for (int n=0; n<lockedChallengeAmount; n++)
{
w->addItem( _("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<DynamicRibbonWidget>("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<const Challenge*>& activeChallenges = unlock_manager->getActiveChallenges();
const std::vector<const Challenge*>& solvedChallenges = unlock_manager->getUnlockedFeatures();
const std::vector<const Challenge*>& lockedChallenges = unlock_manager->getLockedChallenges();
const int activeChallengeAmount = activeChallenges.size();
const int solvedChallengeAmount = solvedChallenges.size();
const int lockedChallengeAmount = lockedChallenges.size();
for (int n=0; n<activeChallengeAmount; n++)
if (selection == "locked")
{
w->addItem(activeChallenges[n]->getName() + L"\n" + activeChallenges[n]->getChallengeDescription(),
activeChallenges[n]->getId(), "/gui/challenge.png");
unlock_manager->playLockSound();
}
for (int n=0; n<solvedChallengeAmount; n++)
else if (!selection.empty())
{
// TODO : add bronze/silver/gold difficulties to challenges
w->addItem(solvedChallenges[n]->getName() + L"\n" + solvedChallenges[n]->getChallengeDescription(),
solvedChallenges[n]->getId(), "/textures/cup_gold.png");
}
for (int n=0; n<lockedChallengeAmount; n++)
{
w->addItem( _("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<DynamicRibbonWidget>("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
}
// ------------------------------------------------------------------------------------------------------

View File

@ -29,6 +29,8 @@ using irr::core::stringc;
#include "guiengine/engine.hpp"
#include "io/file_manager.hpp"
DEFINE_SCREEN_SINGLETON( GUIEngine::CreditsScreen );
namespace GUIEngine
{

View File

@ -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")

View File

@ -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")

View File

@ -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<RibbonWidget>("category");
@ -51,6 +60,10 @@ void HelpScreen1::init()
if (w != NULL) w->select( "page1", GUI_PLAYER_ID );
}
// ------------------------------------------------------------------------------------------------------
void HelpScreen1::tearDown()
{
}
// ------------------------------------------------------------------------------------------------------

View File

@ -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<RibbonWidget>("category");
@ -51,6 +59,10 @@ void HelpScreen2::init()
if (w != NULL) w->select( "page2", GUI_PLAYER_ID );
}
// ------------------------------------------------------------------------------------------------------
void HelpScreen2::tearDown()
{
}
// ------------------------------------------------------------------------------------------------------

View File

@ -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<RibbonWidget>("category");
@ -51,6 +59,10 @@ void HelpScreen3::init()
if (w != NULL) w->select( "page3", GUI_PLAYER_ID );
}
// ------------------------------------------------------------------------------------------------------
void HelpScreen3::tearDown()
{
}
// ------------------------------------------------------------------------------------------------------

View File

@ -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

View File

@ -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<RibbonWidget*>(widget);
@ -121,3 +130,4 @@ void MainMenuScreen::eventCallback(Widget* widget, const std::string& name, cons
}
// ------------------------------------------------------------------------------------------------------

View File

@ -33,11 +33,16 @@
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( OptionsScreenAV );
// -----------------------------------------------------------------------------
OptionsScreenAV::OptionsScreenAV() : Screen("options_av.stkgui")
{
}
// -----------------------------------------------------------------------------
void OptionsScreenAV::init()
{
RibbonWidget* ribbon = this->getWidget<RibbonWidget>("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()
{
}
// -----------------------------------------------------------------------------

View File

@ -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;

View File

@ -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<RibbonWidget>("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
}
// -----------------------------------------------------------------------------

View File

@ -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);

View File

@ -30,6 +30,7 @@
using namespace GUIEngine;
DEFINE_SCREEN_SINGLETON( RaceSetupScreen );
class GameModeRibbonListener : public DynamicRibbonHoverListener
{

View File

@ -34,6 +34,8 @@ using namespace irr::video;
const char* ALL_TRACK_GROUPS_ID = "all";
DEFINE_SCREEN_SINGLETON( TracksScreen );
// -----------------------------------------------------------------------------------------------
TracksScreen::TracksScreen() : Screen("tracks.stkgui")