Skip to content

Commit

Permalink
Fix globules' sprites flickering to white and back.
Browse files Browse the repository at this point in the history
  • Loading branch information
Quipyowert2 committed May 15, 2023
1 parent ad128b2 commit 4d12c90
Show file tree
Hide file tree
Showing 8 changed files with 43 additions and 16 deletions.
3 changes: 2 additions & 1 deletion libgag/include/EventListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ class EventListener {
static std::condition_variable startedCond;
static std::mutex doneMutex;
static std::condition_variable doneCond;
static std::mutex renderMutex;
static std::recursive_mutex renderMutex;
void setPainter(std::function<void()> f);
void addPainter(const std::string& name, std::function<void()> f);
void removePainter(const std::string& name);
static void ensureContext();
void paint();
private:
std::function<void()> painter;
Expand Down
27 changes: 22 additions & 5 deletions libgag/src/EventListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,24 @@ std::mutex EventListener::startMutex;
std::condition_variable EventListener::startedCond;
std::mutex EventListener::doneMutex;
std::condition_variable EventListener::doneCond;
std::mutex EventListener::renderMutex;
std::recursive_mutex EventListener::renderMutex;

#define SIZE_MOVE_TIMER_ID 1
#if defined(_WIN32) || defined(__MINGW32__) || defined(__MINGW64__)
#define WINDOWS_OR_MINGW 1
#endif

// The depth variable is used to return early when indirect recursion happens
EventListener::EventListener(GraphicContext* gfx)
: painter(nullptr), depth(0)
{
assert(gfx);
this->gfx = gfx;
el = this;
done = false;
quit = true;
}

void EventListener::stop()
{
quit = true;
Expand All @@ -49,25 +52,38 @@ void EventListener::stop()
doneCond.wait(lock);
}
}

EventListener::~EventListener()
{
}

// Create an OpenGL context or set existing context as current on this thread.
void EventListener::ensureContext()
{
instance()->gfx->createGLContext();
}

// deprecated; use addPainter/removePainter instead.
void EventListener::setPainter(std::function<void()> f)
{
std::unique_lock<std::mutex> lock(renderMutex);
std::unique_lock<std::recursive_mutex> lock(renderMutex);
painter = f;
}

/* name should be the class name that the function is called on
* f is the function to call to draw the screen.
*/
void EventListener::addPainter(const std::string& name, std::function<void()> f)
{
std::unique_lock<std::mutex> lock(renderMutex);
std::unique_lock<std::recursive_mutex> lock(renderMutex);
painters.insert(std::pair<const std::string, std::function<void()> >(name, f));
}
// Erase the latest painter added with the name `name` from the multimap
void EventListener::removePainter(const std::string& name)
{
if (painters.empty())
assert("Tried to remove a painter when painters map is empty.");
std::unique_lock<std::mutex> lock(renderMutex);
std::unique_lock<std::recursive_mutex> lock(renderMutex);
for (std::multimap<const std::string, std::function<void()> >::reverse_iterator it = painters.rbegin(); it != painters.rend(); ++it)
{
if (it->first == name)
Expand All @@ -79,14 +95,15 @@ void EventListener::removePainter(const std::string& name)
}
}
}
// Draw all the registered painters in order
void EventListener::paint()
{
depth++;
if (depth > 1)
return;
if (painters.size())
{
std::unique_lock<std::mutex> lock(renderMutex);
std::unique_lock<std::recursive_mutex> lock(renderMutex);
gfx->createGLContext();
for (std::multimap<const std::string, std::function<void()> >::iterator it = painters.begin(); it != painters.end(); ++it)
{
Expand Down
7 changes: 3 additions & 4 deletions libgag/src/GUIBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,7 @@ namespace GAGGUI
dispatchEvents(&windowEvent);

// draw
{
std::unique_lock<std::mutex> lock(EventListener::instance()->renderMutex);
dispatchPaint();
}
dispatchPaint();

// wait timer
frameWaitTime=SDL_GetTicks()-frameStartTime;
Expand Down Expand Up @@ -680,6 +677,8 @@ namespace GAGGUI
void Screen::dispatchPaint(void)
{
assert(gfx);
std::unique_lock<std::recursive_mutex> lock(EventListener::renderMutex);
EventListener::ensureContext();
gfx->setClipRect();
paint();
for (std::set<Widget *>::iterator it=widgets.begin(); it!=widgets.end(); ++it)
Expand Down
4 changes: 3 additions & 1 deletion libgag/src/GraphicContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ namespace GAGCore
#ifdef HAVE_OPENGL
if (_gc->optionFlags & GraphicContext::USEGPU)
{
std::unique_lock<std::recursive_mutex> lock(EventListener::renderMutex);
EventListener::ensureContext();
glState.setTexture(texture);

void *pixelsPtr;
Expand Down Expand Up @@ -2061,7 +2063,7 @@ namespace GAGCore
}

SDL_Surface* GraphicContext::getOrCreateSurface(int w, int h, Uint32 flags) {
std::unique_lock<std::mutex> lock(EventListener::instance()->renderMutex);
std::unique_lock<std::recursive_mutex> lock(EventListener::renderMutex);
if (flags & USEGPU)
{
if (sdlsurface)
Expand Down
8 changes: 4 additions & 4 deletions src/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,13 +507,13 @@ int Engine::run(void)
if (nextGuiStep == 0)
{
// we draw
static bool isPainterSet = false;
if (!isPainterSet)
if (!gui.isRegistered)
{
std::unique_lock<std::recursive_mutex> lock(EventListener::renderMutex);
EventListener::instance()->addPainter("GameGUI", std::bind(&GameGUI::drawAll, &gui, gui.localTeamNo));
isPainterSet = true;
gui.isRegistered = true;
}
std::unique_lock<std::mutex> lock(EventListener::instance()->renderMutex);
std::unique_lock<std::recursive_mutex> lock(EventListener::renderMutex);
globalContainer->gfx->createGLContext();
gui.drawAll(gui.localTeamNo);
globalContainer->gfx->nextFrame();
Expand Down
4 changes: 3 additions & 1 deletion src/GameGUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ GameGUI::GameGUI()
128, // width
128, //height
Minimap::ShowFOW), // minimap mode

isRegistered(false),
ghostManager(game)
{
}
Expand Down Expand Up @@ -4385,6 +4385,8 @@ void GameGUI::drawInGameScrollableText(void)

void GameGUI::drawAll(int team)
{
std::unique_lock<std::recursive_mutex> lock(EventListener::renderMutex);
EventListener::ensureContext();
// draw the map
Uint32 drawOptions = (drawHealthFoodBar ? Game::DRAW_HEALTH_FOOD_BAR : 0) |
(drawPathLines ? Game::DRAW_PATH_LINE : 0) |
Expand Down
4 changes: 4 additions & 0 deletions src/GameGUI.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ class GameGUI
bool hardPause;
bool isRunning;
bool notmenu;

// isRegistered tracks whether this instance of GameGUI has been registered with EventListener.
bool isRegistered;

//! true if user close the glob2 window.
bool exitGlobCompletely;
//! true if the game needs to flush all outgoing orders and exit
Expand Down
2 changes: 2 additions & 0 deletions src/MapEdit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1210,6 +1210,8 @@ bool MapEdit::save(const std::string filename, const std::string name)

void MapEdit::draw(void)
{
std::unique_lock<std::recursive_mutex> lock(EventListener::renderMutex);
EventListener::ensureContext();
drawMap(0, 0, globalContainer->gfx->getW() - 0, globalContainer->gfx->getH(), true, true);

drawMenu();
Expand Down

0 comments on commit 4d12c90

Please sign in to comment.