mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-24 03:47:18 +02:00
Replaced SDL user events list with dispatching of arbitrary functors
This commit is contained in:
parent
7fc66c2797
commit
0f8d53e978
@ -451,8 +451,16 @@ static void mainLoop()
|
||||
{
|
||||
SettingsListener resChanged = settings.listen["video"]["resolution"];
|
||||
SettingsListener fsChanged = settings.listen["video"]["fullscreen"];
|
||||
resChanged([](const JsonNode &newState){ GH.pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
|
||||
fsChanged([](const JsonNode &newState){ GH.pushUserEvent(EUserEvent::FULLSCREEN_TOGGLED); });
|
||||
|
||||
auto functor = [](const JsonNode &newState){
|
||||
GH.dispatchMainThread([](){
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
|
||||
GH.onScreenResize();
|
||||
});
|
||||
};
|
||||
|
||||
resChanged(functor);
|
||||
fsChanged(functor);
|
||||
|
||||
inGuiThread.reset(new bool(true));
|
||||
|
||||
|
@ -29,7 +29,6 @@ set(client_SRCS
|
||||
|
||||
eventsSDL/NotificationHandler.cpp
|
||||
eventsSDL/InputHandler.cpp
|
||||
eventsSDL/UserEventHandler.cpp
|
||||
eventsSDL/InputSourceKeyboard.cpp
|
||||
eventsSDL/InputSourceMouse.cpp
|
||||
eventsSDL/InputSourceText.cpp
|
||||
@ -173,7 +172,6 @@ set(client_HEADERS
|
||||
|
||||
eventsSDL/NotificationHandler.h
|
||||
eventsSDL/InputHandler.h
|
||||
eventsSDL/UserEventHandler.h
|
||||
eventsSDL/InputSourceKeyboard.h
|
||||
eventsSDL/InputSourceMouse.h
|
||||
eventsSDL/InputSourceText.h
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "../CCallback.h"
|
||||
#include "windows/CCastleInterface.h"
|
||||
#include "eventsSDL/InputHandler.h"
|
||||
#include "mainmenu/CMainMenu.h"
|
||||
#include "gui/CursorHandler.h"
|
||||
#include "windows/CKingdomInterface.h"
|
||||
#include "CGameInfo.h"
|
||||
@ -1744,7 +1745,16 @@ void CPlayerInterface::requestReturningToMainMenu(bool won)
|
||||
if(won && cb->getStartInfo()->campState)
|
||||
CSH->startCampaignScenario(cb->getStartInfo()->campState);
|
||||
else
|
||||
GH.pushUserEvent(EUserEvent::RETURN_TO_MAIN_MENU);
|
||||
{
|
||||
GH.dispatchMainThread(
|
||||
[]()
|
||||
{
|
||||
CSH->endGameplay();
|
||||
GH.defActionsDef = 63;
|
||||
CMM->menu->switchToTab("main");
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al)
|
||||
@ -1840,7 +1850,21 @@ void CPlayerInterface::waitForAllDialogs(bool unlockPim)
|
||||
|
||||
void CPlayerInterface::proposeLoadingGame()
|
||||
{
|
||||
showYesNoDialog(CGI->generaltexth->allTexts[68], [](){ GH.pushUserEvent(EUserEvent::RETURN_TO_MENU_LOAD); }, nullptr);
|
||||
showYesNoDialog(
|
||||
CGI->generaltexth->allTexts[68],
|
||||
[]()
|
||||
{
|
||||
GH.dispatchMainThread(
|
||||
[]()
|
||||
{
|
||||
CSH->endGameplay();
|
||||
GH.defActionsDef = 63;
|
||||
CMM->menu->switchToTab("load");
|
||||
}
|
||||
);
|
||||
},
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
|
||||
bool CPlayerInterface::capturedAllEvents()
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "windows/InfoWindows.h"
|
||||
|
||||
#include "mainmenu/CMainMenu.h"
|
||||
#include "mainmenu/CPrologEpilogVideo.h"
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
#include "../lib/CAndroidVMHelper.h"
|
||||
@ -662,10 +663,36 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
||||
|
||||
void CServerHandler::startCampaignScenario(std::shared_ptr<CampaignState> cs)
|
||||
{
|
||||
if(cs)
|
||||
GH.pushUserEvent(EUserEvent::CAMPAIGN_START_SCENARIO, CMemorySerializer::deepCopy(*cs.get()).release());
|
||||
else
|
||||
GH.pushUserEvent(EUserEvent::CAMPAIGN_START_SCENARIO, CMemorySerializer::deepCopy(*si->campState.get()).release());
|
||||
std::shared_ptr<CampaignState> ourCampaign = cs;
|
||||
|
||||
if (!cs)
|
||||
ourCampaign = si->campState;
|
||||
|
||||
GH.dispatchMainThread([ourCampaign]()
|
||||
{
|
||||
CSH->campaignServerRestartLock.set(true);
|
||||
CSH->endGameplay();
|
||||
|
||||
auto & epilogue = ourCampaign->scenario(*ourCampaign->lastScenario()).epilog;
|
||||
auto finisher = [=]()
|
||||
{
|
||||
if(!ourCampaign->isCampaignFinished())
|
||||
{
|
||||
GH.windows().pushWindow(CMM);
|
||||
GH.windows().pushWindow(CMM->menu);
|
||||
CMM->openCampaignLobby(ourCampaign);
|
||||
}
|
||||
};
|
||||
if(epilogue.hasPrologEpilog)
|
||||
{
|
||||
GH.windows().createAndPushWindow<CPrologEpilogVideo>(epilogue, finisher);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSH->campaignServerRestartLock.waitUntil(false);
|
||||
finisher();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void CServerHandler::showServerError(std::string txt)
|
||||
@ -842,7 +869,13 @@ void CServerHandler::threadHandleConnection()
|
||||
if(client)
|
||||
{
|
||||
state = EClientState::DISCONNECTING;
|
||||
GH.pushUserEvent(EUserEvent::RETURN_TO_MAIN_MENU);
|
||||
|
||||
GH.dispatchMainThread([]()
|
||||
{
|
||||
CSH->endGameplay();
|
||||
GH.defActionsDef = 63;
|
||||
CMM->menu->switchToTab("main");
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "../CGameInfo.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CServerHandler.h"
|
||||
#include "../PlayerLocalState.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/Shortcut.h"
|
||||
@ -293,8 +294,19 @@ void AdventureMapShortcuts::viewPuzzleMap()
|
||||
|
||||
void AdventureMapShortcuts::restartGame()
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
|
||||
[](){ GH.pushUserEvent(EUserEvent::RESTART_GAME); }, nullptr);
|
||||
LOCPLINT->showYesNoDialog(
|
||||
CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
|
||||
[]()
|
||||
{
|
||||
GH.dispatchMainThread(
|
||||
[]()
|
||||
{
|
||||
CSH->sendRestartGame();
|
||||
}
|
||||
);
|
||||
},
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
|
||||
void AdventureMapShortcuts::visitObject()
|
||||
|
@ -16,7 +16,6 @@
|
||||
#include "InputSourceKeyboard.h"
|
||||
#include "InputSourceTouch.h"
|
||||
#include "InputSourceText.h"
|
||||
#include "UserEventHandler.h"
|
||||
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/CursorHandler.h"
|
||||
@ -35,7 +34,6 @@ InputHandler::InputHandler()
|
||||
, keyboardHandler(std::make_unique<InputSourceKeyboard>())
|
||||
, fingerHandler(std::make_unique<InputSourceTouch>())
|
||||
, textHandler(std::make_unique<InputSourceText>())
|
||||
, userHandler(std::make_unique<UserEventHandler>())
|
||||
{
|
||||
}
|
||||
|
||||
@ -127,7 +125,7 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
|
||||
}
|
||||
else if(ev.type == SDL_USEREVENT)
|
||||
{
|
||||
userHandler->handleUserEvent(ev.user);
|
||||
handleUserEvent(ev.user);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -244,15 +242,25 @@ bool InputHandler::hasTouchInputDevice() const
|
||||
return fingerHandler->hasTouchInputDevice();
|
||||
}
|
||||
|
||||
void InputHandler::pushUserEvent(EUserEvent usercode, void * userdata)
|
||||
void InputHandler::dispatchMainThread(const std::function<void()> & functor)
|
||||
{
|
||||
auto heapFunctor = new std::function<void()>(functor);
|
||||
|
||||
SDL_Event event;
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = static_cast<int32_t>(usercode);
|
||||
event.user.data1 = userdata;
|
||||
event.user.code = 0;
|
||||
event.user.data1 = static_cast <void*>(heapFunctor);
|
||||
event.user.data2 = nullptr;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void InputHandler::handleUserEvent(const SDL_UserEvent & current)
|
||||
{
|
||||
auto heapFunctor = static_cast<std::function<void()>*>(current.data1);
|
||||
|
||||
(*heapFunctor)();
|
||||
}
|
||||
|
||||
const Point & InputHandler::getCursorPosition() const
|
||||
{
|
||||
return cursorPosition;
|
||||
|
@ -15,12 +15,12 @@
|
||||
enum class EUserEvent;
|
||||
enum class MouseButton;
|
||||
union SDL_Event;
|
||||
struct SDL_UserEvent;
|
||||
|
||||
class InputSourceMouse;
|
||||
class InputSourceKeyboard;
|
||||
class InputSourceTouch;
|
||||
class InputSourceText;
|
||||
class UserEventHandler;
|
||||
|
||||
class InputHandler
|
||||
{
|
||||
@ -31,12 +31,12 @@ class InputHandler
|
||||
|
||||
void preprocessEvent(const SDL_Event & event);
|
||||
void handleCurrentEvent(const SDL_Event & current);
|
||||
void handleUserEvent(const SDL_UserEvent & current);
|
||||
|
||||
std::unique_ptr<InputSourceMouse> mouseHandler;
|
||||
std::unique_ptr<InputSourceKeyboard> keyboardHandler;
|
||||
std::unique_ptr<InputSourceTouch> fingerHandler;
|
||||
std::unique_ptr<InputSourceText> textHandler;
|
||||
std::unique_ptr<UserEventHandler> userHandler;
|
||||
|
||||
public:
|
||||
InputHandler();
|
||||
@ -66,8 +66,8 @@ public:
|
||||
/// returns true if system has active touchscreen
|
||||
bool hasTouchInputDevice() const;
|
||||
|
||||
/// Generates new user event that will be processed on next frame
|
||||
void pushUserEvent(EUserEvent usercode, void * userdata);
|
||||
/// Calls provided functor in main thread on next execution frame
|
||||
void dispatchMainThread(const std::function<void()> & functor);
|
||||
|
||||
/// Returns current position of cursor, in VCMI logical screen coordinates
|
||||
const Point & getCursorPosition() const;
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* EventHandlerSDLUser.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "UserEventHandler.h"
|
||||
|
||||
#include "../CMT.h"
|
||||
#include "../CPlayerInterface.h"
|
||||
#include "../CServerHandler.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/WindowHandler.h"
|
||||
#include "../mainmenu/CMainMenu.h"
|
||||
#include "../mainmenu/CPrologEpilogVideo.h"
|
||||
#include "../gui/EventDispatcher.h"
|
||||
|
||||
#include "../../lib/campaign/CampaignState.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
|
||||
void UserEventHandler::handleUserEvent(const SDL_UserEvent & user)
|
||||
{
|
||||
switch(static_cast<EUserEvent>(user.code))
|
||||
{
|
||||
case EUserEvent::FORCE_QUIT:
|
||||
{
|
||||
handleQuit(false);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case EUserEvent::RETURN_TO_MAIN_MENU:
|
||||
{
|
||||
CSH->endGameplay();
|
||||
GH.defActionsDef = 63;
|
||||
CMM->menu->switchToTab("main");
|
||||
}
|
||||
break;
|
||||
case EUserEvent::RESTART_GAME:
|
||||
{
|
||||
CSH->sendRestartGame();
|
||||
}
|
||||
break;
|
||||
case EUserEvent::CAMPAIGN_START_SCENARIO:
|
||||
{
|
||||
CSH->campaignServerRestartLock.set(true);
|
||||
CSH->endGameplay();
|
||||
auto ourCampaign = std::shared_ptr<CampaignState>(reinterpret_cast<CampaignState *>(user.data1));
|
||||
auto & epilogue = ourCampaign->scenario(*ourCampaign->lastScenario()).epilog;
|
||||
auto finisher = [=]()
|
||||
{
|
||||
if(!ourCampaign->isCampaignFinished())
|
||||
{
|
||||
GH.windows().pushWindow(CMM);
|
||||
GH.windows().pushWindow(CMM->menu);
|
||||
CMM->openCampaignLobby(ourCampaign);
|
||||
}
|
||||
};
|
||||
if(epilogue.hasPrologEpilog)
|
||||
{
|
||||
GH.windows().createAndPushWindow<CPrologEpilogVideo>(epilogue, finisher);
|
||||
}
|
||||
else
|
||||
{
|
||||
CSH->campaignServerRestartLock.waitUntil(false);
|
||||
finisher();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EUserEvent::RETURN_TO_MENU_LOAD:
|
||||
CSH->endGameplay();
|
||||
GH.defActionsDef = 63;
|
||||
CMM->menu->switchToTab("load");
|
||||
break;
|
||||
case EUserEvent::FULLSCREEN_TOGGLED:
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*CPlayerInterface::pim);
|
||||
GH.onScreenResize();
|
||||
break;
|
||||
}
|
||||
case EUserEvent::FAKE_MOUSE_MOVE:
|
||||
GH.events().dispatchMouseMoved(Point(0, 0), GH.getCursorPosition());
|
||||
break;
|
||||
default:
|
||||
logGlobal->error("Unknown user event. Code %d", user.code);
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* EventHandlerSDLUser.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
struct SDL_UserEvent;
|
||||
|
||||
/// Class for handling events of type SDL_UserEvent
|
||||
class UserEventHandler
|
||||
{
|
||||
public:
|
||||
void handleUserEvent(const SDL_UserEvent & current);
|
||||
};
|
@ -87,7 +87,9 @@ void CGuiHandler::handleEvents()
|
||||
|
||||
void CGuiHandler::fakeMouseMove()
|
||||
{
|
||||
pushUserEvent(EUserEvent::FAKE_MOUSE_MOVE);
|
||||
dispatchMainThread([](){
|
||||
GH.events().dispatchMouseMoved(Point(0, 0), GH.getCursorPosition());
|
||||
});
|
||||
}
|
||||
|
||||
void CGuiHandler::startTextInput(const Rect & whereInput)
|
||||
@ -203,14 +205,9 @@ bool CGuiHandler::amIGuiThread()
|
||||
return inGuiThread.get() && *inGuiThread;
|
||||
}
|
||||
|
||||
void CGuiHandler::pushUserEvent(EUserEvent usercode)
|
||||
void CGuiHandler::dispatchMainThread(const std::function<void()> & functor)
|
||||
{
|
||||
inputHandlerInstance->pushUserEvent(usercode, nullptr);
|
||||
}
|
||||
|
||||
void CGuiHandler::pushUserEvent(EUserEvent usercode, void * userdata)
|
||||
{
|
||||
inputHandlerInstance->pushUserEvent(usercode, userdata);
|
||||
inputHandlerInstance->dispatchMainThread(functor);
|
||||
}
|
||||
|
||||
IScreenHandler & CGuiHandler::screenHandler()
|
||||
|
@ -27,18 +27,6 @@ class WindowHandler;
|
||||
class EventDispatcher;
|
||||
class InputHandler;
|
||||
|
||||
// TODO: event handling need refactoring. Perhaps convert into delayed function call?
|
||||
enum class EUserEvent
|
||||
{
|
||||
RETURN_TO_MAIN_MENU,
|
||||
RESTART_GAME,
|
||||
RETURN_TO_MENU_LOAD,
|
||||
FULLSCREEN_TOGGLED,
|
||||
CAMPAIGN_START_SCENARIO,
|
||||
FORCE_QUIT,
|
||||
FAKE_MOUSE_MOVE,
|
||||
};
|
||||
|
||||
// Handles GUI logic and drawing
|
||||
class CGuiHandler
|
||||
{
|
||||
@ -108,8 +96,9 @@ public:
|
||||
void drawFPSCounter(); // draws the FPS to the upper left corner of the screen
|
||||
|
||||
bool amIGuiThread();
|
||||
void pushUserEvent(EUserEvent usercode);
|
||||
void pushUserEvent(EUserEvent usercode, void * userdata);
|
||||
|
||||
/// Calls provided functor in main thread on next execution frame
|
||||
void dispatchMainThread(const std::function<void()> & functor);
|
||||
|
||||
CondSh<bool> * terminate_cond; // confirm termination
|
||||
};
|
||||
|
@ -427,10 +427,19 @@ void CBonusSelection::startMap()
|
||||
void CBonusSelection::restartMap()
|
||||
{
|
||||
close();
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [=]()
|
||||
{
|
||||
GH.pushUserEvent(EUserEvent::RESTART_GAME);
|
||||
}, 0);
|
||||
LOCPLINT->showYesNoDialog(
|
||||
CGI->generaltexth->allTexts[67],
|
||||
[=]()
|
||||
{
|
||||
GH.dispatchMainThread(
|
||||
[]()
|
||||
{
|
||||
CSH->sendRestartGame();
|
||||
}
|
||||
);
|
||||
},
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
void CBonusSelection::increaseDifficulty()
|
||||
|
@ -68,7 +68,10 @@ ISelectionScreenInfo * SEL;
|
||||
|
||||
static void do_quit()
|
||||
{
|
||||
GH.pushUserEvent(EUserEvent::FORCE_QUIT);
|
||||
GH.dispatchMainThread([]()
|
||||
{
|
||||
handleQuit(false);
|
||||
});
|
||||
}
|
||||
|
||||
CMenuScreen::CMenuScreen(const JsonNode & configNode)
|
||||
@ -562,10 +565,13 @@ void CSimpleJoinScreen::connectThread(const std::string & addr, ui16 port)
|
||||
else
|
||||
CSH->justConnectToServer(addr, port);
|
||||
|
||||
if(GH.windows().isTopWindow(this))
|
||||
{
|
||||
close();
|
||||
}
|
||||
// async call to prevent thread race
|
||||
GH.dispatchMainThread([this](){
|
||||
if(GH.windows().isTopWindow(this))
|
||||
{
|
||||
close();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
CLoadingScreen::CLoadingScreen(std::function<void()> loader)
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "GeneralOptionsTab.h"
|
||||
#include "OtherOptionsTab.h"
|
||||
|
||||
#include "CMT.h"
|
||||
#include "CGameInfo.h"
|
||||
#include "CGeneralTextHandler.h"
|
||||
#include "CPlayerInterface.h"
|
||||
@ -112,7 +113,18 @@ void SettingsMainWindow::close()
|
||||
|
||||
void SettingsMainWindow::quitGameButtonCallback()
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], [this](){ closeAndPushEvent(EUserEvent::FORCE_QUIT); }, 0);
|
||||
LOCPLINT->showYesNoDialog(
|
||||
CGI->generaltexth->allTexts[578],
|
||||
[this]()
|
||||
{
|
||||
close();
|
||||
GH.dispatchMainThread( []()
|
||||
{
|
||||
handleQuit(false);
|
||||
});
|
||||
},
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
void SettingsMainWindow::backButtonCallback()
|
||||
@ -122,7 +134,20 @@ void SettingsMainWindow::backButtonCallback()
|
||||
|
||||
void SettingsMainWindow::mainMenuButtonCallback()
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], [this](){ closeAndPushEvent(EUserEvent::RETURN_TO_MAIN_MENU); }, 0);
|
||||
LOCPLINT->showYesNoDialog(
|
||||
CGI->generaltexth->allTexts[578],
|
||||
[this]()
|
||||
{
|
||||
close();
|
||||
GH.dispatchMainThread( []()
|
||||
{
|
||||
CSH->endGameplay();
|
||||
GH.defActionsDef = 63;
|
||||
CMM->menu->switchToTab("main");
|
||||
});
|
||||
},
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
void SettingsMainWindow::loadGameButtonCallback()
|
||||
@ -139,13 +164,17 @@ void SettingsMainWindow::saveGameButtonCallback()
|
||||
|
||||
void SettingsMainWindow::restartGameButtonCallback()
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [this](){ closeAndPushEvent(EUserEvent::RESTART_GAME); }, 0);
|
||||
}
|
||||
|
||||
void SettingsMainWindow::closeAndPushEvent(EUserEvent code)
|
||||
{
|
||||
close();
|
||||
GH.pushUserEvent(code);
|
||||
LOCPLINT->showYesNoDialog(
|
||||
CGI->generaltexth->allTexts[67],
|
||||
[this]()
|
||||
{
|
||||
close();
|
||||
GH.dispatchMainThread([](){
|
||||
CSH->sendRestartGame();
|
||||
});
|
||||
},
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
void SettingsMainWindow::showAll(Canvas & to)
|
||||
|
@ -30,7 +30,6 @@ private:
|
||||
void openTab(size_t index);
|
||||
|
||||
void close(); //TODO: copypaste of WindowBase::close(), consider changing Windowbase to IWindowbase with default close() implementation and changing WindowBase inheritance to CIntObject + IWindowBase
|
||||
void closeAndPushEvent(EUserEvent code);
|
||||
|
||||
void loadGameButtonCallback();
|
||||
void saveGameButtonCallback();
|
||||
|
Loading…
x
Reference in New Issue
Block a user