Allow to reuse same stkgui for different screen instance

This commit is contained in:
Benau 2018-03-31 00:11:39 +08:00
parent b1ad185d50
commit 6c56939f49
6 changed files with 39 additions and 43 deletions

View File

@ -52,7 +52,7 @@ void AbstractStateManager::enterGameState()
if (getCurrentScreen() != NULL) getCurrentScreen()->tearDown(); if (getCurrentScreen() != NULL) getCurrentScreen()->tearDown();
m_menu_stack.clear(); m_menu_stack.clear();
m_menu_stack.push_back(RACE_STATE_NAME); m_menu_stack.emplace_back(RACE_STATE_NAME, (Screen*)NULL);
setGameState(GAME); setGameState(GAME);
GUIEngine::cleanForGame(); GUIEngine::cleanForGame();
} // enterGameState } // enterGameState
@ -83,7 +83,7 @@ void AbstractStateManager::setGameState(GameState state)
#pragma mark Push/pop menus #pragma mark Push/pop menus
#endif #endif
void AbstractStateManager::pushMenu(std::string name) void AbstractStateManager::pushMenu(Screen* screen)
{ {
// currently, only a single in-game menu is supported // currently, only a single in-game menu is supported
assert(m_game_mode != INGAME_MENU); assert(m_game_mode != INGAME_MENU);
@ -94,14 +94,14 @@ void AbstractStateManager::pushMenu(std::string name)
if (UserConfigParams::logGUI()) if (UserConfigParams::logGUI())
{ {
Log::info("AbstractStateManager::pushMenu", "Switching to screen %s", Log::info("AbstractStateManager::pushMenu", "Switching to screen %s",
name.c_str()); screen->getName().c_str());
} }
// Send tear-down event to previous menu // Send tear-down event to previous menu
if (m_menu_stack.size() > 0 && m_game_mode != GAME) if (m_menu_stack.size() > 0 && m_game_mode != GAME)
getCurrentScreen()->tearDown(); getCurrentScreen()->tearDown();
m_menu_stack.push_back(name); m_menu_stack.emplace_back(screen->getName(), screen);
if (m_game_mode == GAME) if (m_game_mode == GAME)
{ {
setGameState(INGAME_MENU); setGameState(INGAME_MENU);
@ -110,7 +110,7 @@ void AbstractStateManager::pushMenu(std::string name)
{ {
setGameState(MENU); setGameState(MENU);
} }
switchToScreen(name.c_str()); switchToScreen(screen);
onTopMostScreenChanged(); onTopMostScreenChanged();
} // pushMenu } // pushMenu
@ -130,7 +130,7 @@ void AbstractStateManager::pushScreen(Screen* screen)
} }
if (!screen->isLoaded()) screen->loadFromFile(); if (!screen->isLoaded()) screen->loadFromFile();
pushMenu(screen->getName()); pushMenu(screen);
screen->init(); screen->init();
onTopMostScreenChanged(); onTopMostScreenChanged();
@ -162,9 +162,9 @@ void AbstractStateManager::replaceTopMostScreen(Screen* screen, GUIEngine::GameS
if (getCurrentScreen() != NULL) if (getCurrentScreen() != NULL)
getCurrentScreen()->tearDown(); getCurrentScreen()->tearDown();
m_menu_stack[m_menu_stack.size()-1] = name; m_menu_stack[m_menu_stack.size()-1] = std::make_pair(name, screen);
setGameState(gameState); setGameState(gameState);
switchToScreen(name.c_str()); switchToScreen(screen);
// Send init event to new menu // Send init event to new menu
getCurrentScreen()->init(); getCurrentScreen()->init();
@ -187,7 +187,7 @@ void AbstractStateManager::reshowTopMostMenu()
if (currScreen != NULL) getCurrentScreen()->tearDown(); if (currScreen != NULL) getCurrentScreen()->tearDown();
} }
switchToScreen( m_menu_stack[m_menu_stack.size()-1].c_str() ); switchToScreen(m_menu_stack[m_menu_stack.size()-1].second);
// Send init event to new menu // Send init event to new menu
Screen* screen = getCurrentScreen(); Screen* screen = getCurrentScreen();
@ -216,10 +216,10 @@ void AbstractStateManager::popMenu()
if (UserConfigParams::logGUI()) if (UserConfigParams::logGUI())
{ {
Log::info("AbstractStateManager::popMenu", "Switching to screen %s", Log::info("AbstractStateManager::popMenu", "Switching to screen %s",
m_menu_stack[m_menu_stack.size()-1].c_str()); m_menu_stack[m_menu_stack.size()-1].first.c_str());
} }
if (m_menu_stack[m_menu_stack.size()-1] == RACE_STATE_NAME) if (m_menu_stack[m_menu_stack.size()-1].first == RACE_STATE_NAME)
{ {
setGameState(GAME); setGameState(GAME);
GUIEngine::cleanForGame(); GUIEngine::cleanForGame();
@ -227,7 +227,7 @@ void AbstractStateManager::popMenu()
else else
{ {
setGameState(MENU); setGameState(MENU);
switchToScreen(m_menu_stack[m_menu_stack.size()-1].c_str()); switchToScreen(m_menu_stack[m_menu_stack.size()-1].second);
Screen* screen = getCurrentScreen(); Screen* screen = getCurrentScreen();
if (!screen->isLoaded()) screen->loadFromFile(); if (!screen->isLoaded()) screen->loadFromFile();
@ -254,10 +254,10 @@ void AbstractStateManager::resetAndGoToScreen(Screen* screen)
m_menu_stack.clear(); m_menu_stack.clear();
if (!screen->isLoaded()) screen->loadFromFile(); if (!screen->isLoaded()) screen->loadFromFile();
m_menu_stack.push_back(name); m_menu_stack.emplace_back(name, screen);
setGameState(MENU); setGameState(MENU);
switchToScreen(name.c_str()); switchToScreen(screen);
getCurrentScreen()->init(); getCurrentScreen()->init();
onTopMostScreenChanged(); onTopMostScreenChanged();
@ -277,12 +277,12 @@ void AbstractStateManager::resetAndSetStack(Screen* screens[])
for (int n=0; screens[n] != NULL; n++) for (int n=0; screens[n] != NULL; n++)
{ {
m_menu_stack.push_back(screens[n]->getName()); m_menu_stack.emplace_back(screens[n]->getName(), screens[n]);
} }
setGameState(MENU); setGameState(MENU);
switchToScreen(m_menu_stack[m_menu_stack.size()-1].c_str()); switchToScreen(m_menu_stack[m_menu_stack.size()-1].second);
getCurrentScreen()->init(); getCurrentScreen()->init();
onTopMostScreenChanged(); onTopMostScreenChanged();

View File

@ -59,11 +59,11 @@ namespace GUIEngine
/** /**
* This stack will contain menu names (e.g. main.stkgui), * This stack will contain menu names (e.g. main.stkgui),
* and/or 'race'. * and/or 'race' with screen instance pointer.
*/ */
std::vector<std::string> m_menu_stack; std::vector<std::pair<std::string, Screen*> > m_menu_stack;
void pushMenu(std::string name); void pushMenu(Screen* screen);
void setGameState(GameState state); void setGameState(GameState state);
@ -133,10 +133,10 @@ namespace GUIEngine
T* instance = T::getInstance(); T* instance = T::getInstance();
m_menu_stack.push_back(instance->getName()); m_menu_stack.emplace_back(instance->getName(), instance);
setGameState(MENU); setGameState(MENU);
switchToScreen(instance->getName().c_str()); switchToScreen(instance);
getCurrentScreen()->init(); getCurrentScreen()->init();
onTopMostScreenChanged(); onTopMostScreenChanged();

View File

@ -882,7 +882,7 @@ namespace GUIEngine
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void switchToScreen(const char* screen_name) void switchToScreen(Screen* screen)
{ {
needsUpdate.clearWithoutDeleting(); needsUpdate.clearWithoutDeleting();
@ -893,12 +893,12 @@ namespace GUIEngine
Widget::resetIDCounters(); Widget::resetIDCounters();
// check if we already loaded this screen // check if we already loaded this screen
const int screen_amount = g_loaded_screens.size(); Screen* loaded_screen;
for(int n=0; n<screen_amount; n++) for_in (loaded_screen, g_loaded_screens)
{ {
if (g_loaded_screens[n].getName() == screen_name) if (loaded_screen == screen)
{ {
g_current_screen = g_loaded_screens.get(n); g_current_screen = loaded_screen;
break; break;
} }
} }
@ -925,20 +925,21 @@ namespace GUIEngine
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void removeScreen(const char* name) void removeScreen(Screen* screen)
{ {
const int screen_amount = g_loaded_screens.size(); int n = 0;
for(int n=0; n<screen_amount; n++) Screen* loaded_screen;
for_in (loaded_screen, g_loaded_screens)
{ {
if (g_loaded_screens[n].getName() == name) if (loaded_screen == screen)
{ {
g_current_screen = g_loaded_screens.get(n); screen->unload();
g_current_screen->unload(); delete screen;
delete g_current_screen;
g_current_screen = NULL; g_current_screen = NULL;
g_loaded_screens.remove(n); g_loaded_screens.remove(n);
break; break;
} }
n++;
} }
} }

View File

@ -199,12 +199,12 @@ namespace GUIEngine
/** \brief Add a screen to the list of screens known by the gui engine */ /** \brief Add a screen to the list of screens known by the gui engine */
void addScreenToList(Screen* screen); void addScreenToList(Screen* screen);
/** \brief Remove a screen from the list of screens known by the gui engine */ /** \brief Remove a screen from the list of screens known by the gui engine */
void removeScreen(const char* name); void removeScreen(Screen* screen);
/** \brief Low-level mean to change current screen. /** \brief Low-level mean to change current screen.
* \note Do not use directly. Use a state manager instead to get higher-level functionnality. * \note Do not use directly. Use a state manager instead to get higher-level functionnality.
*/ */
void switchToScreen(const char* ); void switchToScreen(Screen* screen);
/** \brief erases the currently displayed screen, removing all added irrLicht widgets /** \brief erases the currently displayed screen, removing all added irrLicht widgets
* \note Do not use directly. Use a state manager instead to get higher-level functionnality. * \note Do not use directly. Use a state manager instead to get higher-level functionnality.

View File

@ -425,7 +425,9 @@ void KartSelectionScreen::tearDown()
Screen::tearDown(); Screen::tearDown();
m_kart_widgets.clearAndDeleteAll(); m_kart_widgets.clearAndDeleteAll();
GUIEngine::removeScreen(getName().c_str()); if (m_must_delete_on_back)
GUIEngine::removeScreen(this);
} // tearDown } // tearDown
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -54,13 +54,6 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual bool playerQuit(StateManager::ActivePlayer* player) OVERRIDE virtual bool playerQuit(StateManager::ActivePlayer* player) OVERRIDE
{ return true; } { return true; }
// ------------------------------------------------------------------------
/** \brief implement callback from parent class GUIEngine::Screen */
virtual void tearDown() OVERRIDE
{
m_must_delete_on_back = true;
KartSelectionScreen::tearDown();
}
}; };