Improved the design of the GUI engine yet a bit more. Documented a couple coding horrors with FIXMEs *blush*

git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@5258 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
auria
2010-04-24 20:21:04 +00:00
parent 400a102241
commit ad97efc12f
4 changed files with 47 additions and 16 deletions

View File

@@ -19,13 +19,12 @@
#include "guiengine/abstract_state_manager.hpp"
#include <vector>
#include "main_loop.hpp"
#include "audio/sfx_manager.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/screen.hpp"
#include "input/device_manager.hpp"
#include "input/input_manager.hpp"
#include "modes/world.hpp"
using namespace GUIEngine;
@@ -61,13 +60,15 @@ GameState AbstractStateManager::getGameState()
return m_game_mode;
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
#if 0
#pragma mark -
#pragma mark Push/pop menus
#endif
// -----------------------------------------------------------------------------
void AbstractStateManager::pushMenu(std::string name)
{
// currently, only a single in-game menu is supported
@@ -81,9 +82,6 @@ void AbstractStateManager::pushMenu(std::string name)
if (m_game_mode == GAME)
{
setGameState(INGAME_MENU);
//FIXME: this doesn't go in the *abstract* state manager
if (World::getWorld() != NULL) World::getWorld()->pause();
}
else
{
@@ -93,6 +91,7 @@ void AbstractStateManager::pushMenu(std::string name)
}
// -----------------------------------------------------------------------------
void AbstractStateManager::pushScreen(Screen* screen)
{
pushMenu(screen->getName());
@@ -100,6 +99,7 @@ void AbstractStateManager::pushScreen(Screen* screen)
}
// -----------------------------------------------------------------------------
void AbstractStateManager::replaceTopMostScreen(Screen* screen)
{
assert(m_game_mode != GAME);
@@ -110,6 +110,9 @@ void AbstractStateManager::replaceTopMostScreen(Screen* screen)
if (m_menu_stack.size() > 0) getCurrentScreen()->tearDown();
//FIXME: this doesn't go in the *abstract* state manager
//FIXME: I don't understand this line. since this can't be called in game mode, why
// is a switch necessary? why don't we check what the new topmost menu is before
// changing input mode? why do we change input mode but NOT game mode?
input_manager->setMode(InputManager::MENU);
m_menu_stack[m_menu_stack.size()-1] = name;
@@ -120,6 +123,7 @@ void AbstractStateManager::replaceTopMostScreen(Screen* screen)
}
// -----------------------------------------------------------------------------
void AbstractStateManager::reshowTopMostMenu()
{
assert(m_game_mode != GAME);
@@ -138,6 +142,7 @@ void AbstractStateManager::reshowTopMostMenu()
}
// -----------------------------------------------------------------------------
void AbstractStateManager::popMenu()
{
assert(m_game_mode != GAME);
@@ -148,8 +153,7 @@ void AbstractStateManager::popMenu()
if (m_menu_stack.size() == 0)
{
//FIXME: this doesn't go in the *abstract* state manager
main_loop->abort();
onStackEmptied();
return;
}
@@ -157,12 +161,9 @@ void AbstractStateManager::popMenu()
if (m_menu_stack[m_menu_stack.size()-1] == "race")
{
//FIXME: I check that the top item is 'race', then push it again so it's there twice??? WTF??
m_menu_stack.push_back("race");
if (m_game_mode == INGAME_MENU)
{
//FIXME: this doesn't go in the *abstract* state manager
if (World::getWorld() != NULL) World::getWorld()->unpause();
}
setGameState(GAME);
GUIEngine::cleanForGame();
@@ -178,6 +179,7 @@ void AbstractStateManager::popMenu()
}
// -----------------------------------------------------------------------------
void AbstractStateManager::setGameState(GameState state)
{
if (m_game_mode == state) return; // no change
@@ -195,7 +197,7 @@ void AbstractStateManager::resetAndGoToScreen(Screen* screen)
std::string name = screen->getName();
//FIXME: this doesn't go in the *abstract* state manager
assert(World::getWorld()==NULL);
//assert(World::getWorld()==NULL);
if (m_game_mode != GAME) getCurrentScreen()->tearDown();
m_menu_stack.clear();

View File

@@ -109,6 +109,13 @@ namespace GUIEngine
*/
virtual void onGameStateChange(GameState previousState, GameState newState) = 0;
/**
* \brief callback invoked when the stack is emptied (all menus are popped out)
* This is essentially a request to close the application (since a game can't run
* without a state)
*/
virtual void onStackEmptied() = 0;
};
}

View File

@@ -25,6 +25,8 @@
#include "guiengine/screen.hpp"
#include "input/input_device.hpp"
#include "input/input_manager.hpp"
#include "main_loop.hpp"
#include "modes/world.hpp"
#include "states_screens/dialogs/race_paused_dialog.hpp"
#include "utils/translation.hpp"
@@ -179,18 +181,36 @@ void StateManager::onGameStateChange(GameState previousState, GameState newState
if (newState == GAME)
{
irr_driver->hidePointer();
if (previousState == INGAME_MENU)
{
// unpause the world
if (World::getWorld() != NULL) World::getWorld()->unpause();
}
}
else // menu (including in-game menu)
{
irr_driver->showPointer();
if (m_game_mode == MENU)
if (newState == MENU)
{
music_manager->startMusic(stk_config->m_title_music);
}
else if (newState == INGAME_MENU)
{
// pause game when an in-game menu is shown
if (World::getWorld() != NULL) World::getWorld()->pause();
}
}
}
// ----------------------------------------------------------------------------
void StateManager::onStackEmptied()
{
main_loop->abort();
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------

View File

@@ -138,6 +138,8 @@ public:
/** \brief implementing callback from base class AbstractStateManager */
virtual void onGameStateChange(GUIEngine::GameState previousState, GUIEngine::GameState newState);
/** \brief implementing callback from base class AbstractStateManager */
virtual void onStackEmptied();
// singleton
static StateManager* get();