1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-21 21:17:49 +02:00

* fixed remaining part of — 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:
Michał W. Urbańczyk 2012-09-11 14:25:19 +00:00
parent d935e87dd8
commit 96a92d0f45
8 changed files with 54 additions and 52 deletions

@ -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