1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

SDL event handling is now done exclusively in input handler

This commit is contained in:
Ivan Savenko 2023-05-18 23:31:05 +03:00
parent 5e86b00dda
commit 0e70f2998f
14 changed files with 52 additions and 78 deletions

View File

@ -45,8 +45,6 @@
#undef main
#endif
extern boost::mutex eventsM;
namespace po = boost::program_options;
namespace po_style = boost::program_options::command_line_style;
namespace bfs = boost::filesystem;
@ -528,15 +526,7 @@ void handleQuit(bool ask)
if(CSH->client && LOCPLINT && ask)
{
CCS->curh->set(Cursor::Map::POINTER);
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], [](){
// Workaround for assertion failure on exit:
// handleQuit() is alway called during SDL event processing
// during which, eventsM is kept locked
// this leads to assertion failure if boost::mutex is in locked state
eventsM.unlock();
quitApplication();
}, nullptr);
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[69], quitApplication, nullptr);
}
else
{

View File

@ -22,6 +22,7 @@
#include "battle/BattleWindow.h"
#include "../CCallback.h"
#include "windows/CCastleInterface.h"
#include "eventsSDL/InputHandler.h"
#include "gui/CursorHandler.h"
#include "windows/CKingdomInterface.h"
#include "CGameInfo.h"
@ -77,8 +78,6 @@
#include "eventsSDL/NotificationHandler.h"
#include "adventureMap/CInGameConsole.h"
#include <SDL_events.h>
// The macro below is used to mark functions that are called by client when game state changes.
// They all assume that CPlayerInterface::pim mutex is locked.
#define EVENT_HANDLER_CALLED_BY_CLIENT
@ -96,8 +95,6 @@
return; \
RETURN_IF_QUICK_COMBAT
extern std::queue<SDL_Event> SDLEventsQueue;
extern boost::mutex eventsM;
boost::recursive_mutex * CPlayerInterface::pim = new boost::recursive_mutex;
CPlayerInterface * LOCPLINT;
@ -206,7 +203,7 @@ void CPlayerInterface::performAutosave()
}
else if(frequency > 0 && cb->getDate() % frequency == 0)
{
LOCPLINT->cb->save("Saves/" + prefix + "Autosave_" + std::to_string(autosaveCount++ + 1));
cb->save("Saves/" + prefix + "Autosave_" + std::to_string(autosaveCount++ + 1));
autosaveCount %= 5;
}
}
@ -215,8 +212,6 @@ void CPlayerInterface::yourTurn()
{
EVENT_HANDLER_CALLED_BY_CLIENT;
{
boost::unique_lock<boost::mutex> lock(eventsM); //block handling events until interface is ready
LOCPLINT = this;
GH.curInt = this;
@ -372,22 +367,8 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose)
//check if user cancelled movement
{
boost::unique_lock<boost::mutex> un(eventsM);
while(!SDLEventsQueue.empty())
{
SDL_Event ev = SDLEventsQueue.front();
SDLEventsQueue.pop();
switch(ev.type)
{
case SDL_MOUSEBUTTONDOWN:
stillMoveHero.setn(STOP_MOVE);
break;
case SDL_KEYDOWN:
if (ev.key.keysym.sym < SDLK_F1 || ev.key.keysym.sym > SDLK_F15)
stillMoveHero.setn(STOP_MOVE);
break;
}
}
if (GH.input().ignoreEventsUntilInput())
stillMoveHero.setn(STOP_MOVE);
}
if (stillMoveHero.get() == WAITING_MOVE)
@ -1478,7 +1459,6 @@ void CPlayerInterface::playerBlocked(int reason, bool start)
if(CSH->howManyPlayerInterfaces() > 1 && LOCPLINT != this && LOCPLINT->makingTurn == false)
{
//one of our players who isn't last in order got attacked not by our another player (happens for example in hotseat mode)
boost::unique_lock<boost::mutex> lock(eventsM); //TODO: copied from yourTurn, no idea if it's needed
LOCPLINT = this;
GH.curInt = this;
adventureInt->onCurrentPlayerChanged(playerID);
@ -1875,11 +1855,7 @@ bool CPlayerInterface::capturedAllEvents()
if (ignoreEvents || needToLockAdventureMap || isAutoFightOn)
{
boost::unique_lock<boost::mutex> un(eventsM);
while(!SDLEventsQueue.empty())
{
SDLEventsQueue.pop();
}
GH.input().ignoreEventsUntilInput();
return true;
}

View File

@ -12,15 +12,13 @@
#include "CMT.h"
#include "gui/CGuiHandler.h"
#include "eventsSDL/InputHandler.h"
#include "gui/FramerateManager.h"
#include "renderSDL/SDL_Extensions.h"
#include "CPlayerInterface.h"
#include "../lib/filesystem/Filesystem.h"
#include <SDL_render.h>
#include <SDL_events.h>
extern CGuiHandler GH; //global gui handler
#ifndef DISABLE_VIDEO
@ -31,18 +29,6 @@ extern "C" {
#include <libswscale/swscale.h>
}
//reads events and returns true on key down
static bool keyDown()
{
SDL_Event ev;
while(SDL_PollEvent(&ev))
{
if(ev.type == SDL_KEYDOWN || ev.type == SDL_MOUSEBUTTONDOWN)
return true;
}
return false;
}
#ifdef _MSC_VER
#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avutil.lib")
@ -455,7 +441,9 @@ bool CVideoPlayer::playVideo(int x, int y, bool stopOnKey)
while(nextFrame())
{
if(stopOnKey && keyDown())
GH.input().fetchEvents();
if(stopOnKey && GH.input().ignoreEventsUntilInput())
return false;
SDL_Rect rect = CSDL_Ext::toSDL(pos);

View File

@ -17,6 +17,7 @@
#include "../CGameInfo.h"
#include "../CPlayerInterface.h"
#include "../gui/CGuiHandler.h"
#include "../gui/MouseButton.h"
#include "../gui/WindowHandler.h"
#include "../render/Colors.h"
#include "../renderSDL/SDL_Extensions.h"

View File

@ -25,6 +25,7 @@
#include "../gui/CursorHandler.h"
#include "../gui/CGuiHandler.h"
#include "../gui/Shortcut.h"
#include "../gui/MouseButton.h"
#include "../gui/WindowHandler.h"
#include "../render/Canvas.h"
#include "../render/IImage.h"

View File

@ -21,6 +21,7 @@
#include "../gui/CGuiHandler.h"
#include "../gui/CursorHandler.h"
#include "../gui/EventDispatcher.h"
#include "../gui/MouseButton.h"
#include "../CMT.h"
#include "../CPlayerInterface.h"
#include "../CGameInfo.h"
@ -29,8 +30,6 @@
#include <SDL_events.h>
std::queue<SDL_Event> SDLEventsQueue;
boost::mutex eventsM;
InputHandler::InputHandler()
: mouseHandler(std::make_unique<InputSourceMouse>())
@ -100,6 +99,27 @@ void InputHandler::processEvents()
}
}
bool InputHandler::ignoreEventsUntilInput()
{
bool inputFound = false;
boost::unique_lock<boost::mutex> lock(eventsM);
while(!SDLEventsQueue.empty())
{
SDL_Event ev = SDLEventsQueue.front();
SDLEventsQueue.pop();
switch(ev.type)
{
case SDL_MOUSEBUTTONDOWN:
case SDL_FINGERDOWN:
case SDL_KEYDOWN:
inputFound = true;
}
}
return inputFound;
}
void InputHandler::preprocessEvent(const SDL_Event & ev)
{
if((ev.type==SDL_QUIT) ||(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
@ -154,7 +174,8 @@ void InputHandler::preprocessEvent(const SDL_Event & ev)
//preprocessing
if(ev.type == SDL_MOUSEMOTION)
{
CCS->curh->cursorMove(ev.motion.x, ev.motion.y);
if (CCS && CCS->curh)
CCS->curh->cursorMove(ev.motion.x, ev.motion.y);
}
{

View File

@ -24,6 +24,9 @@ class UserEventHandler;
class InputHandler
{
std::queue<SDL_Event> SDLEventsQueue;
boost::mutex eventsM;
Point cursorPosition;
float pointerSpeedMultiplier;
int mouseButtonsMask;
@ -44,6 +47,10 @@ public:
void fetchEvents();
void processEvents();
/// drops all incoming events without processing them
/// returns true if input event has been found
bool ignoreEventsUntilInput();
void fakeMoveCursor(float dx, float dy);
void startTextInput(const Rect & where);
void stopTextInput();

View File

@ -17,6 +17,7 @@
#include "../CMT.h"
#include "../gui/CGuiHandler.h"
#include "../gui/EventDispatcher.h"
#include "../gui/MouseButton.h"
#include <SDL_events.h>
#include <SDL_render.h>

View File

@ -34,9 +34,6 @@
CGuiHandler GH;
extern std::queue<SDL_Event> SDLEventsQueue;
extern boost::mutex eventsM;
boost::thread_specific_ptr<bool> inGuiThread;
SObjectConstruction::SObjectConstruction(CIntObject *obj)
@ -198,11 +195,6 @@ Point CGuiHandler::screenDimensions() const
return Point(screen->w, screen->h);
}
bool CGuiHandler::isMouseButtonPressed() const
{
return isMouseButtonPressed(MouseButton::LEFT) || isMouseButtonPressed(MouseButton::MIDDLE) || isMouseButtonPressed(MouseButton::RIGHT);
}
bool CGuiHandler::isMouseButtonPressed(MouseButton button) const
{
return inputHandlerInstance->isMouseButtonPressed(button);

View File

@ -9,19 +9,13 @@
*/
#pragma once
#include "MouseButton.h"
#include "../../lib/Point.h"
VCMI_LIB_NAMESPACE_BEGIN
template <typename T> struct CondSh;
class Point;
class Rect;
VCMI_LIB_NAMESPACE_END
union SDL_Event;
struct SDL_MouseMotionEvent;
enum class MouseButton;
class ShortcutHandler;
class FramerateManager;
class IStatusBar;
@ -75,9 +69,6 @@ public:
/// May not match size of window if user has UI scaling different from 100%
Point screenDimensions() const;
/// returns true if at least one mouse button is pressed
bool isMouseButtonPressed() const;
/// returns true if specified mouse button is pressed
bool isMouseButtonPressed(MouseButton button) const;

View File

@ -13,6 +13,9 @@
#include "EventsReceiver.h"
#include "FramerateManager.h"
#include "CGuiHandler.h"
#include "MouseButton.h"
#include "../../lib/Point.h"
void EventDispatcher::allowEventHandling(bool enable)
{

View File

@ -15,6 +15,7 @@
#include "../CGameInfo.h"
#include "../CServerHandler.h"
#include "../gui/CGuiHandler.h"
#include "../gui/MouseButton.h"
#include "../gui/WindowHandler.h"
#include "../widgets/CComponent.h"
#include "../widgets/Buttons.h"

View File

@ -18,6 +18,7 @@
#include "../adventureMap/AdventureMapInterface.h"
#include "../gui/CGuiHandler.h"
#include "../gui/CursorHandler.h"
#include "../gui/MouseButton.h"
#include "../../lib/CConfigHandler.h"

View File

@ -19,6 +19,7 @@
#include "../battle/BattleInterface.h"
#include "../battle/BattleInterfaceClasses.h"
#include "../gui/CGuiHandler.h"
#include "../gui/MouseButton.h"
#include "../gui/Shortcut.h"
#include "../windows/InfoWindows.h"
#include "../render/CAnimation.h"