Skip to content

Commit

Permalink
WIP: Fix crash when resizing.
Browse files Browse the repository at this point in the history
EventListener::paint can indirectly recurse by way of WindowProc.
  • Loading branch information
Quipyowert2 committed Apr 24, 2023
1 parent ddef414 commit 73576a5
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 6 deletions.
1 change: 1 addition & 0 deletions libgag/include/EventListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class EventListener {
GraphicContext* gfx;
static EventListener* el;
std::atomic<bool> quit, done;
std::atomic<int> depth;
};
}
#endif //__EVENTLISTENER_H
14 changes: 9 additions & 5 deletions libgag/src/EventListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ std::mutex EventListener::renderMutex;
#endif

EventListener::EventListener(GraphicContext* gfx)
: painter(nullptr)
: painter(nullptr), depth(0)
{
this->gfx = gfx;
el = this;
Expand Down Expand Up @@ -68,19 +68,22 @@ 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);
for (auto it = painters.rbegin(); it != painters.rend();++it)
for (std::multimap<const std::string, std::function<void()> >::reverse_iterator it = painters.rbegin(); it != painters.rend(); ++it)
{
if (it->first == name)
{
// There might be multiple Screens active, so we remove the one added last.
// For example, a Screen with an OverlayScreen above it.
painters.erase(it.base());
painters.erase(--(it.base()));
break;
}
}
}
void EventListener::paint()
{
depth++;
if (depth > 1)
return;
if (painters.size())
{
std::unique_lock<std::mutex> lock(renderMutex);
Expand All @@ -91,6 +94,7 @@ void EventListener::paint()
}
gfx->nextFrame();
}
depth--;
}
//https://stackoverflow.com/a/51597338/8890345
#ifdef WINDOWS_OR_MINGW
Expand Down Expand Up @@ -124,8 +128,8 @@ void EventListener::run()
{
std::unique_lock<std::mutex> lock(startMutex);
quit = false;
startedCond.notify_one();
}
startedCond.notify_one();
#ifdef WINDOWS_OR_MINGW
SDL_AddEventWatch(eventWatch, this); // register the event watch function
SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE); // we need the native Windows events, so we can listen to WM_ENTERSIZEMOVE and WM_TIMER
Expand Down Expand Up @@ -165,8 +169,8 @@ void EventListener::run()
{
std::unique_lock<std::mutex> lock(doneMutex);
done = true;
doneCond.notify_one();
}
doneCond.notify_one();
}
int EventListener::poll(SDL_Event* e)
{
Expand Down
5 changes: 4 additions & 1 deletion libgag/src/GUIBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,10 @@ namespace GAGGUI
dispatchEvents(&windowEvent);

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

// wait timer
frameWaitTime=SDL_GetTicks()-frameStartTime;
Expand Down

0 comments on commit 73576a5

Please sign in to comment.