2
0
Эх сурвалжийг харах

* 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)

Michał W. Urbańczyk 13 жил өмнө
parent
commit
96a92d0f45

+ 1 - 4
client/BattleInterface/CBattleInterfaceClasses.cpp

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

+ 20 - 17
client/CMT.cpp

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

+ 5 - 9
client/CPlayerInterface.cpp

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

+ 5 - 2
client/CPlayerInterface.h

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

+ 10 - 14
client/GUIClasses.cpp

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

+ 1 - 2
client/GUIClasses.h

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

+ 11 - 4
client/UIFramework/CGuiHandler.cpp

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

+ 1 - 0
client/UIFramework/CGuiHandler.h

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