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

View File

@ -59,11 +59,11 @@ namespace GUIEngine
/**
* 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);
@ -133,10 +133,10 @@ namespace GUIEngine
T* instance = T::getInstance();
m_menu_stack.push_back(instance->getName());
m_menu_stack.emplace_back(instance->getName(), instance);
setGameState(MENU);
switchToScreen(instance->getName().c_str());
switchToScreen(instance);
getCurrentScreen()->init();
onTopMostScreenChanged();

View File

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

View File

@ -199,12 +199,12 @@ namespace GUIEngine
/** \brief Add a screen to the list of screens known by the gui engine */
void addScreenToList(Screen* screen);
/** \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.
* \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
* \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();
m_kart_widgets.clearAndDeleteAll();
GUIEngine::removeScreen(getName().c_str());
if (m_must_delete_on_back)
GUIEngine::removeScreen(this);
} // tearDown
// ----------------------------------------------------------------------------

View File

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