mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-21 21:17:49 +02:00
* fixed remaining part of #1071 — the screen surface has always to be created in the main thread
* hold events in the queue by value (less ptr jugglery)
This commit is contained in:
parent
d935e87dd8
commit
96a92d0f45
client
@ -477,10 +477,7 @@ void CBattleResultWindow::bExitf()
|
||||
{
|
||||
if(LOCPLINT->cb->getStartInfo()->mode == StartInfo::DUEL)
|
||||
{
|
||||
SDL_Event ev;
|
||||
ev.type = SDL_QUIT;
|
||||
ev.user.code = 0;
|
||||
SDL_PushEvent(&ev);
|
||||
CGuiHandler::pushSDLEvent(SDL_QUIT);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ SDL_Surface *screen = NULL, //main screen surface
|
||||
*screenBuf = screen; //points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed
|
||||
static boost::thread *mainGUIThread;
|
||||
|
||||
std::queue<SDL_Event*> events;
|
||||
std::queue<SDL_Event> events;
|
||||
boost::mutex eventsM;
|
||||
|
||||
static bool gOnlyAI = false;
|
||||
@ -690,14 +690,16 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen, bool resetVideo
|
||||
//setResolution = true;
|
||||
}
|
||||
|
||||
static void fullScreenChanged(const JsonNode &newState)
|
||||
static void fullScreenChanged()
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*LOCPLINT->pim);
|
||||
|
||||
bool fullscreen = newState.Bool();
|
||||
Settings full = settings.write["video"]["fullscreen"];
|
||||
const bool toFullscreen = full->Bool();
|
||||
|
||||
int bitsPerPixel = screen->format->BitsPerPixel;
|
||||
|
||||
bitsPerPixel = SDL_VideoModeOK(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0));
|
||||
bitsPerPixel = SDL_VideoModeOK(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(toFullscreen?SDL_FULLSCREEN:0));
|
||||
if(bitsPerPixel == 0)
|
||||
{
|
||||
tlog1 << "Error: SDL says that " << screen->w << "x" << screen->h << " resolution is not available!\n";
|
||||
@ -705,7 +707,7 @@ static void fullScreenChanged(const JsonNode &newState)
|
||||
}
|
||||
|
||||
bool bufOnScreen = (screenBuf == screen);
|
||||
screen = SDL_SetVideoMode(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(fullscreen?SDL_FULLSCREEN:0));
|
||||
screen = SDL_SetVideoMode(screen->w, screen->h, bitsPerPixel, SDL_SWSURFACE|(toFullscreen?SDL_FULLSCREEN:0));
|
||||
screenBuf = bufOnScreen ? screen : screen2;
|
||||
|
||||
GH.totalRedraw();
|
||||
@ -714,17 +716,17 @@ static void fullScreenChanged(const JsonNode &newState)
|
||||
static void listenForEvents()
|
||||
{
|
||||
SettingsListener resChanged = settings.listen["video"]["fullscreen"];
|
||||
resChanged(fullScreenChanged);
|
||||
resChanged([](const JsonNode &newState){ CGuiHandler::pushSDLEvent(SDL_USEREVENT, FULLSCREEN_TOGGLED); });
|
||||
|
||||
while(1) //main SDL events loop
|
||||
{
|
||||
SDL_Event *ev = new SDL_Event();
|
||||
SDL_Event ev;
|
||||
|
||||
//tlog0 << "Waiting... ";
|
||||
int ret = SDL_WaitEvent(ev);
|
||||
//tlog0 << "got " << (int)ev->type;
|
||||
if (ret == 0 || (ev->type==SDL_QUIT) ||
|
||||
(ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT)))
|
||||
int ret = SDL_WaitEvent(&ev);
|
||||
//tlog0 << "got " << (int)ev.type;
|
||||
if (ret == 0 || (ev.type==SDL_QUIT) ||
|
||||
(ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4 && (ev.key.keysym.mod & KMOD_ALT)))
|
||||
{
|
||||
if (client)
|
||||
client->endGame();
|
||||
@ -742,14 +744,13 @@ static void listenForEvents()
|
||||
tlog0 << "Ending...\n";
|
||||
break;
|
||||
}
|
||||
else if(LOCPLINT && ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4)
|
||||
else if(LOCPLINT && ev.type == SDL_KEYDOWN && ev.key.keysym.sym==SDLK_F4)
|
||||
{
|
||||
Settings full = settings.write["video"]["fullscreen"];
|
||||
full->Bool() = !full->Bool();
|
||||
delete ev;
|
||||
continue;
|
||||
}
|
||||
else if(ev->type == SDL_USEREVENT)
|
||||
else if(ev.type == SDL_USEREVENT)
|
||||
{
|
||||
auto endGame = []
|
||||
{
|
||||
@ -761,7 +762,7 @@ static void listenForEvents()
|
||||
const_cast<CGameInfo*>(CGI)->dobjinfo->load();
|
||||
};
|
||||
|
||||
switch(ev->user.code)
|
||||
switch(ev.user.code)
|
||||
{
|
||||
/* case CHANGE_SCREEN_RESOLUTION:
|
||||
{
|
||||
@ -795,12 +796,14 @@ static void listenForEvents()
|
||||
CGP->menu->switchToTab(vstd::find_pos(CGP->menu->menuNameToEntry, "load"));
|
||||
GH.curInt = CGP;
|
||||
break;
|
||||
case FULLSCREEN_TOGGLED:
|
||||
fullScreenChanged();
|
||||
break;
|
||||
default:
|
||||
tlog1 << "Error: unknown user event. Code " << ev->user.code << std::endl;
|
||||
tlog1 << "Error: unknown user event. Code " << ev.user.code << std::endl;
|
||||
assert(0);
|
||||
}
|
||||
|
||||
delete ev;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ using namespace CSDL_Ext;
|
||||
|
||||
void processCommand(const std::string &message, CClient *&client);
|
||||
|
||||
extern std::queue<SDL_Event*> events;
|
||||
extern std::queue<SDL_Event> events;
|
||||
extern boost::mutex eventsM;
|
||||
boost::recursive_mutex * CPlayerInterface::pim = new boost::recursive_mutex;
|
||||
|
||||
@ -334,19 +334,18 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
boost::unique_lock<boost::mutex> un(eventsM);
|
||||
while(events.size())
|
||||
{
|
||||
SDL_Event *ev = events.front();
|
||||
SDL_Event ev = events.front();
|
||||
events.pop();
|
||||
switch(ev->type)
|
||||
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)
|
||||
if(ev.key.keysym.sym < SDLK_F1 || ev.key.keysym.sym > SDLK_F15)
|
||||
stillMoveHero.setn(STOP_MOVE);
|
||||
break;
|
||||
}
|
||||
delete ev;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2295,10 +2294,7 @@ void CPlayerInterface::requestStoppingClient()
|
||||
|
||||
void CPlayerInterface::sendCustomEvent( int code )
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type = SDL_USEREVENT;
|
||||
event.user.code = code;
|
||||
SDL_PushEvent(&event);
|
||||
CGuiHandler::pushSDLEvent(SDL_USEREVENT, code);
|
||||
}
|
||||
|
||||
void CPlayerInterface::stackChagedCount(const StackLocation &location, const TQuantity &change, bool isAbsolute)
|
||||
|
@ -71,12 +71,15 @@ namespace boost
|
||||
class recursive_mutex;
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
/*CHANGE_SCREEN_RESOLUTION = 1,*/
|
||||
RETURN_TO_MAIN_MENU = 2,
|
||||
STOP_CLIENT = 3,
|
||||
RESTART_GAME,
|
||||
RETURN_TO_MENU_LOAD};
|
||||
RETURN_TO_MENU_LOAD,
|
||||
FULLSCREEN_TOGGLED
|
||||
};
|
||||
|
||||
/// Central class for managing user interface logic
|
||||
class CPlayerInterface : public CGameInterface, public IUpdateable
|
||||
|
@ -57,7 +57,7 @@
|
||||
using namespace boost::assign;
|
||||
using namespace CSDL_Ext;
|
||||
|
||||
extern std::queue<SDL_Event*> events;
|
||||
extern std::queue<SDL_Event> events;
|
||||
extern boost::mutex eventsM;
|
||||
|
||||
std::list<CFocusable*> CFocusable::focusables;
|
||||
@ -3439,16 +3439,6 @@ void CSystemOptionsWindow::setGameRes(int index)
|
||||
gameRes["height"].Float() = iter->first.second;
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::pushSDLEvent(int type, int usercode)
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
|
||||
SDL_Event event;
|
||||
event.type = type;
|
||||
event.user.code = usercode; // not necessarily used
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::toggleReminder(bool on)
|
||||
{
|
||||
Settings heroReminder = settings.write["adventure"]["heroReminder"];
|
||||
@ -3469,7 +3459,7 @@ void CSystemOptionsWindow::toggleFullscreen(bool on)
|
||||
|
||||
void CSystemOptionsWindow::bquitf()
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], boost::bind(&CSystemOptionsWindow::pushSDLEvent, this, SDL_QUIT, 0), 0, false);
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], [this]{ closeAndPushEvent(SDL_QUIT); }, 0);
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::breturnf()
|
||||
@ -3479,7 +3469,7 @@ void CSystemOptionsWindow::breturnf()
|
||||
|
||||
void CSystemOptionsWindow::bmainmenuf()
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], boost::bind(&CSystemOptionsWindow::pushSDLEvent, this, SDL_USEREVENT, RETURN_TO_MAIN_MENU), 0, false);
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[578], [this]{ closeAndPushEvent(SDL_USEREVENT, RETURN_TO_MAIN_MENU); }, 0);
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::bloadf()
|
||||
@ -3496,7 +3486,13 @@ void CSystemOptionsWindow::bsavef()
|
||||
|
||||
void CSystemOptionsWindow::brestartf()
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], boost::bind(&CSystemOptionsWindow::pushSDLEvent, this, SDL_USEREVENT, RESTART_GAME), 0, false);
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[67], [this]{ closeAndPushEvent(SDL_USEREVENT, RESTART_GAME); }, 0);
|
||||
}
|
||||
|
||||
void CSystemOptionsWindow::closeAndPushEvent(int eventType, int code /*= 0*/)
|
||||
{
|
||||
GH.popIntTotally(this);
|
||||
GH.pushSDLEvent(eventType, code);
|
||||
}
|
||||
|
||||
CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj):
|
||||
|
@ -750,8 +750,7 @@ private:
|
||||
|
||||
void selectGameRes();
|
||||
void setGameRes(int index);
|
||||
|
||||
void pushSDLEvent(int type, int usercode);
|
||||
void closeAndPushEvent(int eventType, int code = 0);
|
||||
|
||||
public:
|
||||
CSystemOptionsWindow(); //c-tor
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "../CConfigHandler.h"
|
||||
|
||||
extern SDL_Surface * screenBuf, * screen2, * screen;
|
||||
extern std::queue<SDL_Event*> events;
|
||||
extern std::queue<SDL_Event> events;
|
||||
extern boost::mutex eventsM;
|
||||
|
||||
boost::thread_specific_ptr<bool> inGuiThread;
|
||||
@ -126,7 +126,7 @@ void CGuiHandler::handleEvents()
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
SDL_Event *ev = NULL;
|
||||
SDL_Event ev;
|
||||
boost::unique_lock<boost::mutex> lock(eventsM);
|
||||
if(!events.size())
|
||||
{
|
||||
@ -137,8 +137,7 @@ void CGuiHandler::handleEvents()
|
||||
ev = events.front();
|
||||
events.pop();
|
||||
}
|
||||
handleEvent(ev);
|
||||
delete ev;
|
||||
handleEvent(&ev);
|
||||
}
|
||||
}
|
||||
|
||||
@ -448,6 +447,14 @@ bool CGuiHandler::amIGuiThread()
|
||||
return inGuiThread.get() && *inGuiThread;
|
||||
}
|
||||
|
||||
void CGuiHandler::pushSDLEvent(int type, int usercode)
|
||||
{
|
||||
SDL_Event event;
|
||||
event.type = type;
|
||||
event.user.code = usercode; // not necessarily used
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
CFramerateManager::CFramerateManager(int rate)
|
||||
{
|
||||
this->rate = rate;
|
||||
|
@ -95,6 +95,7 @@ public:
|
||||
static bool isNumKey(SDLKey key, bool number = true); //checks if key is on numpad (numbers - check only for numpad digits)
|
||||
static bool isArrowKey(SDLKey key);
|
||||
static bool amIGuiThread();
|
||||
static void pushSDLEvent(int type, int usercode = 0);
|
||||
};
|
||||
|
||||
extern CGuiHandler GH; //global gui handler
|
||||
|
Loading…
x
Reference in New Issue
Block a user