1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-22 22:13:35 +02:00

CGuiHandler: use std:atomic to sync breaks in event handling

This commit is contained in:
Arseniy Shestakov 2017-09-11 00:00:46 +03:00 committed by ArseniyShestakov
parent 986fc08b1e
commit 494872937a
2 changed files with 36 additions and 36 deletions

View File

@ -187,21 +187,19 @@ void CGuiHandler::handleEvents()
boost::unique_lock<boost::mutex> lock(eventsM); boost::unique_lock<boost::mutex> lock(eventsM);
while(!events.empty()) while(!events.empty())
{ {
SDL_Event ev = events.front(); continueEventHandling = true;
current = &events.front();
events.pop(); events.pop();
this->handleEvent(&ev); handleCurrentEvent();
} }
} }
void CGuiHandler::handleEvent(SDL_Event *sEvent) void CGuiHandler::handleCurrentEvent()
{ {
current = sEvent; if(current->type == SDL_KEYDOWN || current->type == SDL_KEYUP)
bool prev;
if (sEvent->type==SDL_KEYDOWN || sEvent->type==SDL_KEYUP)
{ {
SDL_KeyboardEvent key = sEvent->key; SDL_KeyboardEvent key = current->key;
if(sEvent->type == SDL_KEYDOWN && key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool()) if(current->type == SDL_KEYDOWN && key.keysym.sym >= SDLK_F1 && key.keysym.sym <= SDLK_F15 && settings["session"]["spectate"].Bool())
{ {
//TODO: we need some central place for all interface-independent hotkeys //TODO: we need some central place for all interface-independent hotkeys
Settings s = settings.write["session"]; Settings s = settings.write["session"];
@ -250,7 +248,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
} }
bool keysCaptured = false; bool keysCaptured = false;
for(auto i=keyinterested.begin(); i != keyinterested.end() && current; i++) for(auto i = keyinterested.begin(); i != keyinterested.end() && continueEventHandling; i++)
{ {
if((*i)->captureThisEvent(key)) if((*i)->captureThisEvent(key))
{ {
@ -260,27 +258,27 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
} }
std::list<CIntObject*> miCopy = keyinterested; std::list<CIntObject*> miCopy = keyinterested;
for(auto i=miCopy.begin(); i != miCopy.end() && current; i++) for(auto i = miCopy.begin(); i != miCopy.end() && continueEventHandling; i++)
if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisEvent(key))) if(vstd::contains(keyinterested,*i) && (!keysCaptured || (*i)->captureThisEvent(key)))
(**i).keyPressed(key); (**i).keyPressed(key);
} }
else if(sEvent->type==SDL_MOUSEMOTION) else if(current->type == SDL_MOUSEMOTION)
{ {
CCS->curh->cursorMove(sEvent->motion.x, sEvent->motion.y); CCS->curh->cursorMove(current->motion.x, current->motion.y);
handleMouseMotion(sEvent); handleMouseMotion();
} }
else if(sEvent->type == SDL_MOUSEBUTTONDOWN) else if(current->type == SDL_MOUSEBUTTONDOWN)
{ {
switch(sEvent->button.button) switch(current->button.button)
{ {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
if(lastClick == sEvent->motion && (SDL_GetTicks() - lastClickTime) < 300) if(lastClick == current->motion && (SDL_GetTicks() - lastClickTime) < 300)
{ {
std::list<CIntObject*> hlp = doubleClickInterested; std::list<CIntObject*> hlp = doubleClickInterested;
for(auto i = hlp.begin(); i != hlp.end() && current; i++) for(auto i = hlp.begin(); i != hlp.end() && continueEventHandling; i++)
{ {
if(!vstd::contains(doubleClickInterested, *i)) continue; if(!vstd::contains(doubleClickInterested, *i)) continue;
if(isItIn(&(*i)->pos, sEvent->motion.x, sEvent->motion.y)) if(isItIn(&(*i)->pos, current->motion.x, current->motion.y))
{ {
(*i)->onDoubleClick(); (*i)->onDoubleClick();
} }
@ -288,7 +286,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
} }
lastClick = sEvent->motion; lastClick = current->motion;
lastClickTime = SDL_GetTicks(); lastClickTime = SDL_GetTicks();
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, true); handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, true);
@ -303,36 +301,36 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
break; break;
} }
} }
else if (sEvent->type == SDL_MOUSEWHEEL) else if(current->type == SDL_MOUSEWHEEL)
{ {
std::list<CIntObject*> hlp = wheelInterested; std::list<CIntObject*> hlp = wheelInterested;
for(auto i=hlp.begin(); i != hlp.end() && current; i++) for(auto i = hlp.begin(); i != hlp.end() && continueEventHandling; i++)
{ {
if(!vstd::contains(wheelInterested,*i)) continue; if(!vstd::contains(wheelInterested,*i)) continue;
// SDL doesn't have the proper values for mouse positions on SDL_MOUSEWHEEL, refetch them // SDL doesn't have the proper values for mouse positions on SDL_MOUSEWHEEL, refetch them
int x = 0, y = 0; int x = 0, y = 0;
SDL_GetMouseState(&x, &y); SDL_GetMouseState(&x, &y);
(*i)->wheelScrolled(sEvent->wheel.y < 0, isItIn(&(*i)->pos, x, y)); (*i)->wheelScrolled(current->wheel.y < 0, isItIn(&(*i)->pos, x, y));
} }
} }
else if(sEvent->type == SDL_TEXTINPUT) else if(current->type == SDL_TEXTINPUT)
{ {
for(auto it : textInterested) for(auto it : textInterested)
{ {
it->textInputed(sEvent->text); it->textInputed(current->text);
} }
} }
else if(sEvent->type == SDL_TEXTEDITING) else if(current->type == SDL_TEXTEDITING)
{ {
for(auto it : textInterested) for(auto it : textInterested)
{ {
it->textEdited(sEvent->edit); it->textEdited(current->edit);
} }
} }
//todo: muiltitouch //todo: muiltitouch
else if(sEvent->type == SDL_MOUSEBUTTONUP) else if(current->type == SDL_MOUSEBUTTONUP)
{ {
switch(sEvent->button.button) switch(current->button.button)
{ {
case SDL_BUTTON_LEFT: case SDL_BUTTON_LEFT:
handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, false); handleMouseButtonClick(lclickable, EIntObjMouseBtnType::LEFT, false);
@ -351,7 +349,7 @@ void CGuiHandler::handleEvent(SDL_Event *sEvent)
void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed) void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntObjMouseBtnType btn, bool isPressed)
{ {
auto hlp = interestedObjs; auto hlp = interestedObjs;
for(auto i = hlp.begin(); i != hlp.end() && current; i++) for(auto i = hlp.begin(); i != hlp.end() && continueEventHandling; i++)
{ {
if(!vstd::contains(interestedObjs, *i)) continue; if(!vstd::contains(interestedObjs, *i)) continue;
@ -369,13 +367,13 @@ void CGuiHandler::handleMouseButtonClick(CIntObjectList & interestedObjs, EIntOb
} }
} }
void CGuiHandler::handleMouseMotion(SDL_Event *sEvent) void CGuiHandler::handleMouseMotion()
{ {
//sending active, hovered hoverable objects hover() call //sending active, hovered hoverable objects hover() call
std::vector<CIntObject*> hlp; std::vector<CIntObject*> hlp;
for(auto & elem : hoverable) for(auto & elem : hoverable)
{ {
if (isItIn(&(elem)->pos,sEvent->motion.x,sEvent->motion.y)) if(isItIn(&(elem)->pos, current->motion.x, current->motion.y))
{ {
if (!(elem)->hovered) if (!(elem)->hovered)
hlp.push_back((elem)); hlp.push_back((elem));
@ -392,7 +390,7 @@ void CGuiHandler::handleMouseMotion(SDL_Event *sEvent)
elem->hovered = true; elem->hovered = true;
} }
handleMoveInterested(sEvent->motion); handleMoveInterested(current->motion);
} }
void CGuiHandler::simpleRedraw() void CGuiHandler::simpleRedraw()
@ -470,6 +468,7 @@ void CGuiHandler::renderFrame()
CGuiHandler::CGuiHandler() CGuiHandler::CGuiHandler()
: lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false) : lastClick(-500, -500),lastClickTime(0), defActionsDef(0), captureChildren(false)
{ {
continueEventHandling = true;
curInt = nullptr; curInt = nullptr;
current = nullptr; current = nullptr;
statusbar = nullptr; statusbar = nullptr;
@ -489,7 +488,7 @@ CGuiHandler::~CGuiHandler()
void CGuiHandler::breakEventHandling() void CGuiHandler::breakEventHandling()
{ {
current = nullptr; continueEventHandling = false;
} }
void CGuiHandler::drawFPSCounter() void CGuiHandler::drawFPSCounter()

View File

@ -48,6 +48,7 @@ public:
CGStatusBar * statusbar; CGStatusBar * statusbar;
private: private:
std::atomic<bool> continueEventHandling;
typedef std::list<CIntObject*> CIntObjectList; typedef std::list<CIntObject*> CIntObjectList;
//active GUI elements (listening for events //active GUI elements (listening for events
@ -99,8 +100,8 @@ public:
void updateTime(); //handles timeInterested void updateTime(); //handles timeInterested
void handleEvents(); //takes events from queue and calls interested objects void handleEvents(); //takes events from queue and calls interested objects
void handleEvent(SDL_Event *sEvent); void handleCurrentEvent();
void handleMouseMotion(SDL_Event *sEvent); void handleMouseMotion();
void handleMoveInterested( const SDL_MouseMotionEvent & motion ); void handleMoveInterested( const SDL_MouseMotionEvent & motion );
void fakeMouseMove(); void fakeMouseMove();
void breakEventHandling(); //current event won't be propagated anymore void breakEventHandling(); //current event won't be propagated anymore