mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-17 01:32:21 +02:00
Replaced SDL user events list with dispatching of arbitrary functors
This commit is contained in:
@ -451,8 +451,16 @@ static void mainLoop()
|
|||||||
{
|
{
|
||||||
SettingsListener resChanged = settings.listen["video"]["resolution"];
|
SettingsListener resChanged = settings.listen["video"]["resolution"];
|
||||||
SettingsListener fsChanged = settings.listen["video"]["fullscreen"];
|
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));
|
inGuiThread.reset(new bool(true));
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ set(client_SRCS
|
|||||||
|
|
||||||
eventsSDL/NotificationHandler.cpp
|
eventsSDL/NotificationHandler.cpp
|
||||||
eventsSDL/InputHandler.cpp
|
eventsSDL/InputHandler.cpp
|
||||||
eventsSDL/UserEventHandler.cpp
|
|
||||||
eventsSDL/InputSourceKeyboard.cpp
|
eventsSDL/InputSourceKeyboard.cpp
|
||||||
eventsSDL/InputSourceMouse.cpp
|
eventsSDL/InputSourceMouse.cpp
|
||||||
eventsSDL/InputSourceText.cpp
|
eventsSDL/InputSourceText.cpp
|
||||||
@ -173,7 +172,6 @@ set(client_HEADERS
|
|||||||
|
|
||||||
eventsSDL/NotificationHandler.h
|
eventsSDL/NotificationHandler.h
|
||||||
eventsSDL/InputHandler.h
|
eventsSDL/InputHandler.h
|
||||||
eventsSDL/UserEventHandler.h
|
|
||||||
eventsSDL/InputSourceKeyboard.h
|
eventsSDL/InputSourceKeyboard.h
|
||||||
eventsSDL/InputSourceMouse.h
|
eventsSDL/InputSourceMouse.h
|
||||||
eventsSDL/InputSourceText.h
|
eventsSDL/InputSourceText.h
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "../CCallback.h"
|
#include "../CCallback.h"
|
||||||
#include "windows/CCastleInterface.h"
|
#include "windows/CCastleInterface.h"
|
||||||
#include "eventsSDL/InputHandler.h"
|
#include "eventsSDL/InputHandler.h"
|
||||||
|
#include "mainmenu/CMainMenu.h"
|
||||||
#include "gui/CursorHandler.h"
|
#include "gui/CursorHandler.h"
|
||||||
#include "windows/CKingdomInterface.h"
|
#include "windows/CKingdomInterface.h"
|
||||||
#include "CGameInfo.h"
|
#include "CGameInfo.h"
|
||||||
@ -1744,7 +1745,16 @@ void CPlayerInterface::requestReturningToMainMenu(bool won)
|
|||||||
if(won && cb->getStartInfo()->campState)
|
if(won && cb->getStartInfo()->campState)
|
||||||
CSH->startCampaignScenario(cb->getStartInfo()->campState);
|
CSH->startCampaignScenario(cb->getStartInfo()->campState);
|
||||||
else
|
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)
|
void CPlayerInterface::askToAssembleArtifact(const ArtifactLocation &al)
|
||||||
@ -1840,7 +1850,21 @@ void CPlayerInterface::waitForAllDialogs(bool unlockPim)
|
|||||||
|
|
||||||
void CPlayerInterface::proposeLoadingGame()
|
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()
|
bool CPlayerInterface::capturedAllEvents()
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "windows/InfoWindows.h"
|
#include "windows/InfoWindows.h"
|
||||||
|
|
||||||
#include "mainmenu/CMainMenu.h"
|
#include "mainmenu/CMainMenu.h"
|
||||||
|
#include "mainmenu/CPrologEpilogVideo.h"
|
||||||
|
|
||||||
#ifdef VCMI_ANDROID
|
#ifdef VCMI_ANDROID
|
||||||
#include "../lib/CAndroidVMHelper.h"
|
#include "../lib/CAndroidVMHelper.h"
|
||||||
@ -662,10 +663,36 @@ void CServerHandler::endGameplay(bool closeConnection, bool restart)
|
|||||||
|
|
||||||
void CServerHandler::startCampaignScenario(std::shared_ptr<CampaignState> cs)
|
void CServerHandler::startCampaignScenario(std::shared_ptr<CampaignState> cs)
|
||||||
{
|
{
|
||||||
if(cs)
|
std::shared_ptr<CampaignState> ourCampaign = cs;
|
||||||
GH.pushUserEvent(EUserEvent::CAMPAIGN_START_SCENARIO, CMemorySerializer::deepCopy(*cs.get()).release());
|
|
||||||
else
|
if (!cs)
|
||||||
GH.pushUserEvent(EUserEvent::CAMPAIGN_START_SCENARIO, CMemorySerializer::deepCopy(*si->campState.get()).release());
|
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)
|
void CServerHandler::showServerError(std::string txt)
|
||||||
@ -842,7 +869,13 @@ void CServerHandler::threadHandleConnection()
|
|||||||
if(client)
|
if(client)
|
||||||
{
|
{
|
||||||
state = EClientState::DISCONNECTING;
|
state = EClientState::DISCONNECTING;
|
||||||
GH.pushUserEvent(EUserEvent::RETURN_TO_MAIN_MENU);
|
|
||||||
|
GH.dispatchMainThread([]()
|
||||||
|
{
|
||||||
|
CSH->endGameplay();
|
||||||
|
GH.defActionsDef = 63;
|
||||||
|
CMM->menu->switchToTab("main");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "../CGameInfo.h"
|
#include "../CGameInfo.h"
|
||||||
#include "../CPlayerInterface.h"
|
#include "../CPlayerInterface.h"
|
||||||
|
#include "../CServerHandler.h"
|
||||||
#include "../PlayerLocalState.h"
|
#include "../PlayerLocalState.h"
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../gui/Shortcut.h"
|
#include "../gui/Shortcut.h"
|
||||||
@ -293,8 +294,19 @@ void AdventureMapShortcuts::viewPuzzleMap()
|
|||||||
|
|
||||||
void AdventureMapShortcuts::restartGame()
|
void AdventureMapShortcuts::restartGame()
|
||||||
{
|
{
|
||||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
|
LOCPLINT->showYesNoDialog(
|
||||||
[](){ GH.pushUserEvent(EUserEvent::RESTART_GAME); }, nullptr);
|
CGI->generaltexth->translate("vcmi.adventureMap.confirmRestartGame"),
|
||||||
|
[]()
|
||||||
|
{
|
||||||
|
GH.dispatchMainThread(
|
||||||
|
[]()
|
||||||
|
{
|
||||||
|
CSH->sendRestartGame();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
nullptr
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdventureMapShortcuts::visitObject()
|
void AdventureMapShortcuts::visitObject()
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
#include "InputSourceKeyboard.h"
|
#include "InputSourceKeyboard.h"
|
||||||
#include "InputSourceTouch.h"
|
#include "InputSourceTouch.h"
|
||||||
#include "InputSourceText.h"
|
#include "InputSourceText.h"
|
||||||
#include "UserEventHandler.h"
|
|
||||||
|
|
||||||
#include "../gui/CGuiHandler.h"
|
#include "../gui/CGuiHandler.h"
|
||||||
#include "../gui/CursorHandler.h"
|
#include "../gui/CursorHandler.h"
|
||||||
@ -35,7 +34,6 @@ InputHandler::InputHandler()
|
|||||||
, keyboardHandler(std::make_unique<InputSourceKeyboard>())
|
, keyboardHandler(std::make_unique<InputSourceKeyboard>())
|
||||||
, fingerHandler(std::make_unique<InputSourceTouch>())
|
, fingerHandler(std::make_unique<InputSourceTouch>())
|
||||||
, textHandler(std::make_unique<InputSourceText>())
|
, 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)
|
else if(ev.type == SDL_USEREVENT)
|
||||||
{
|
{
|
||||||
userHandler->handleUserEvent(ev.user);
|
handleUserEvent(ev.user);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -244,15 +242,25 @@ bool InputHandler::hasTouchInputDevice() const
|
|||||||
return fingerHandler->hasTouchInputDevice();
|
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;
|
SDL_Event event;
|
||||||
event.type = SDL_USEREVENT;
|
event.type = SDL_USEREVENT;
|
||||||
event.user.code = static_cast<int32_t>(usercode);
|
event.user.code = 0;
|
||||||
event.user.data1 = userdata;
|
event.user.data1 = static_cast <void*>(heapFunctor);
|
||||||
|
event.user.data2 = nullptr;
|
||||||
SDL_PushEvent(&event);
|
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
|
const Point & InputHandler::getCursorPosition() const
|
||||||
{
|
{
|
||||||
return cursorPosition;
|
return cursorPosition;
|
||||||
|
@ -15,12 +15,12 @@
|
|||||||
enum class EUserEvent;
|
enum class EUserEvent;
|
||||||
enum class MouseButton;
|
enum class MouseButton;
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
|
struct SDL_UserEvent;
|
||||||
|
|
||||||
class InputSourceMouse;
|
class InputSourceMouse;
|
||||||
class InputSourceKeyboard;
|
class InputSourceKeyboard;
|
||||||
class InputSourceTouch;
|
class InputSourceTouch;
|
||||||
class InputSourceText;
|
class InputSourceText;
|
||||||
class UserEventHandler;
|
|
||||||
|
|
||||||
class InputHandler
|
class InputHandler
|
||||||
{
|
{
|
||||||
@ -31,12 +31,12 @@ class InputHandler
|
|||||||
|
|
||||||
void preprocessEvent(const SDL_Event & event);
|
void preprocessEvent(const SDL_Event & event);
|
||||||
void handleCurrentEvent(const SDL_Event & current);
|
void handleCurrentEvent(const SDL_Event & current);
|
||||||
|
void handleUserEvent(const SDL_UserEvent & current);
|
||||||
|
|
||||||
std::unique_ptr<InputSourceMouse> mouseHandler;
|
std::unique_ptr<InputSourceMouse> mouseHandler;
|
||||||
std::unique_ptr<InputSourceKeyboard> keyboardHandler;
|
std::unique_ptr<InputSourceKeyboard> keyboardHandler;
|
||||||
std::unique_ptr<InputSourceTouch> fingerHandler;
|
std::unique_ptr<InputSourceTouch> fingerHandler;
|
||||||
std::unique_ptr<InputSourceText> textHandler;
|
std::unique_ptr<InputSourceText> textHandler;
|
||||||
std::unique_ptr<UserEventHandler> userHandler;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InputHandler();
|
InputHandler();
|
||||||
@ -66,8 +66,8 @@ public:
|
|||||||
/// returns true if system has active touchscreen
|
/// returns true if system has active touchscreen
|
||||||
bool hasTouchInputDevice() const;
|
bool hasTouchInputDevice() const;
|
||||||
|
|
||||||
/// Generates new user event that will be processed on next frame
|
/// Calls provided functor in main thread on next execution frame
|
||||||
void pushUserEvent(EUserEvent usercode, void * userdata);
|
void dispatchMainThread(const std::function<void()> & functor);
|
||||||
|
|
||||||
/// Returns current position of cursor, in VCMI logical screen coordinates
|
/// Returns current position of cursor, in VCMI logical screen coordinates
|
||||||
const Point & getCursorPosition() const;
|
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()
|
void CGuiHandler::fakeMouseMove()
|
||||||
{
|
{
|
||||||
pushUserEvent(EUserEvent::FAKE_MOUSE_MOVE);
|
dispatchMainThread([](){
|
||||||
|
GH.events().dispatchMouseMoved(Point(0, 0), GH.getCursorPosition());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGuiHandler::startTextInput(const Rect & whereInput)
|
void CGuiHandler::startTextInput(const Rect & whereInput)
|
||||||
@ -203,14 +205,9 @@ bool CGuiHandler::amIGuiThread()
|
|||||||
return inGuiThread.get() && *inGuiThread;
|
return inGuiThread.get() && *inGuiThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGuiHandler::pushUserEvent(EUserEvent usercode)
|
void CGuiHandler::dispatchMainThread(const std::function<void()> & functor)
|
||||||
{
|
{
|
||||||
inputHandlerInstance->pushUserEvent(usercode, nullptr);
|
inputHandlerInstance->dispatchMainThread(functor);
|
||||||
}
|
|
||||||
|
|
||||||
void CGuiHandler::pushUserEvent(EUserEvent usercode, void * userdata)
|
|
||||||
{
|
|
||||||
inputHandlerInstance->pushUserEvent(usercode, userdata);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IScreenHandler & CGuiHandler::screenHandler()
|
IScreenHandler & CGuiHandler::screenHandler()
|
||||||
|
@ -27,18 +27,6 @@ class WindowHandler;
|
|||||||
class EventDispatcher;
|
class EventDispatcher;
|
||||||
class InputHandler;
|
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
|
// Handles GUI logic and drawing
|
||||||
class CGuiHandler
|
class CGuiHandler
|
||||||
{
|
{
|
||||||
@ -108,8 +96,9 @@ public:
|
|||||||
void drawFPSCounter(); // draws the FPS to the upper left corner of the screen
|
void drawFPSCounter(); // draws the FPS to the upper left corner of the screen
|
||||||
|
|
||||||
bool amIGuiThread();
|
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
|
CondSh<bool> * terminate_cond; // confirm termination
|
||||||
};
|
};
|
||||||
|
@ -427,10 +427,19 @@ void CBonusSelection::startMap()
|
|||||||
void CBonusSelection::restartMap()
|
void CBonusSelection::restartMap()
|
||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [=]()
|
LOCPLINT->showYesNoDialog(
|
||||||
{
|
CGI->generaltexth->allTexts[67],
|
||||||
GH.pushUserEvent(EUserEvent::RESTART_GAME);
|
[=]()
|
||||||
}, 0);
|
{
|
||||||
|
GH.dispatchMainThread(
|
||||||
|
[]()
|
||||||
|
{
|
||||||
|
CSH->sendRestartGame();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBonusSelection::increaseDifficulty()
|
void CBonusSelection::increaseDifficulty()
|
||||||
|
@ -68,7 +68,10 @@ ISelectionScreenInfo * SEL;
|
|||||||
|
|
||||||
static void do_quit()
|
static void do_quit()
|
||||||
{
|
{
|
||||||
GH.pushUserEvent(EUserEvent::FORCE_QUIT);
|
GH.dispatchMainThread([]()
|
||||||
|
{
|
||||||
|
handleQuit(false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CMenuScreen::CMenuScreen(const JsonNode & configNode)
|
CMenuScreen::CMenuScreen(const JsonNode & configNode)
|
||||||
@ -562,10 +565,13 @@ void CSimpleJoinScreen::connectThread(const std::string & addr, ui16 port)
|
|||||||
else
|
else
|
||||||
CSH->justConnectToServer(addr, port);
|
CSH->justConnectToServer(addr, port);
|
||||||
|
|
||||||
if(GH.windows().isTopWindow(this))
|
// async call to prevent thread race
|
||||||
{
|
GH.dispatchMainThread([this](){
|
||||||
close();
|
if(GH.windows().isTopWindow(this))
|
||||||
}
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
CLoadingScreen::CLoadingScreen(std::function<void()> loader)
|
CLoadingScreen::CLoadingScreen(std::function<void()> loader)
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "GeneralOptionsTab.h"
|
#include "GeneralOptionsTab.h"
|
||||||
#include "OtherOptionsTab.h"
|
#include "OtherOptionsTab.h"
|
||||||
|
|
||||||
|
#include "CMT.h"
|
||||||
#include "CGameInfo.h"
|
#include "CGameInfo.h"
|
||||||
#include "CGeneralTextHandler.h"
|
#include "CGeneralTextHandler.h"
|
||||||
#include "CPlayerInterface.h"
|
#include "CPlayerInterface.h"
|
||||||
@ -112,7 +113,18 @@ void SettingsMainWindow::close()
|
|||||||
|
|
||||||
void SettingsMainWindow::quitGameButtonCallback()
|
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()
|
void SettingsMainWindow::backButtonCallback()
|
||||||
@ -122,7 +134,20 @@ void SettingsMainWindow::backButtonCallback()
|
|||||||
|
|
||||||
void SettingsMainWindow::mainMenuButtonCallback()
|
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()
|
void SettingsMainWindow::loadGameButtonCallback()
|
||||||
@ -139,13 +164,17 @@ void SettingsMainWindow::saveGameButtonCallback()
|
|||||||
|
|
||||||
void SettingsMainWindow::restartGameButtonCallback()
|
void SettingsMainWindow::restartGameButtonCallback()
|
||||||
{
|
{
|
||||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [this](){ closeAndPushEvent(EUserEvent::RESTART_GAME); }, 0);
|
LOCPLINT->showYesNoDialog(
|
||||||
}
|
CGI->generaltexth->allTexts[67],
|
||||||
|
[this]()
|
||||||
void SettingsMainWindow::closeAndPushEvent(EUserEvent code)
|
{
|
||||||
{
|
close();
|
||||||
close();
|
GH.dispatchMainThread([](){
|
||||||
GH.pushUserEvent(code);
|
CSH->sendRestartGame();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
0
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SettingsMainWindow::showAll(Canvas & to)
|
void SettingsMainWindow::showAll(Canvas & to)
|
||||||
|
@ -30,7 +30,6 @@ private:
|
|||||||
void openTab(size_t index);
|
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 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 loadGameButtonCallback();
|
||||||
void saveGameButtonCallback();
|
void saveGameButtonCallback();
|
||||||
|
Reference in New Issue
Block a user