Skip to content

Commit

Permalink
Work around broken event pushing on Tiger
Browse files Browse the repository at this point in the history
Pushing events from a background thread on Tiger + SDL1
does not appear to do anything at all.

I don't know if the issue is limited to Tiger,
so apply the workaround on all macOS when using SDL1.
  • Loading branch information
glebm committed Dec 11, 2024
1 parent 4ca21e7 commit dd6d51d
Showing 1 changed file with 68 additions and 10 deletions.
78 changes: 68 additions & 10 deletions Source/interfac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@ namespace devilution {

namespace {

#if defined(__APPLE__) && defined(USE_SDL1)
// On Tiger PPC, SDL_PushEvent from a background thread appears to do nothing.
#define SDL_PUSH_EVENT_BG_THREAD_WORKS 0
#else
#define SDL_PUSH_EVENT_BG_THREAD_WORKS 1
#endif

#if !SDL_PUSH_EVENT_BG_THREAD_WORKS
// This workaround is not completely thread-safe but the worst
// that can happen is we miss some WM_PROGRESS events,
// which is not a problem.
struct {
std::atomic<int> type;
std::string error;
} NextCustomEvent;
#endif

constexpr uint32_t MaxProgress = 534;
constexpr uint32_t ProgressStepSize = 23;

Expand Down Expand Up @@ -391,16 +408,31 @@ void DoLoad(interface_mode uMsg)
}

if (!loadResult.has_value()) {
#if SDL_PUSH_EVENT_BG_THREAD_WORKS
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_ERROR);
event.user.data1 = new std::string(std::move(loadResult).error());
SDL_PushEvent(&event);
if (SDL_PushEvent(&event) < 0) {
LogError("Failed to send WM_ERROR {}", SDL_GetError());
SDL_ClearError();
}
#else
NextCustomEvent.error = std::move(loadResult).error();
NextCustomEvent.type = static_cast<int>(WM_ERROR);
#endif
return;
}

#if SDL_PUSH_EVENT_BG_THREAD_WORKS
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_DONE);
SDL_PushEvent(&event);
if (SDL_PushEvent(&event) < 0) {
LogError("Failed to send WM_DONE {}", SDL_GetError());
SDL_ClearError();
}
#else
NextCustomEvent.type = static_cast<int>(WM_DONE);
#endif
}

struct {
Expand Down Expand Up @@ -561,9 +593,16 @@ void IncProgress(uint32_t steps)
if (sgdwProgress > MaxProgress)
sgdwProgress = MaxProgress;
if (!HeadlessMode && sgdwProgress != prevProgress) {
#if SDL_PUSH_EVENT_BG_THREAD_WORKS
SDL_Event event;
event.type = CustomEventToSdlEvent(WM_PROGRESS);
SDL_PushEvent(&event);
if (SDL_PushEvent(&event) < 0) {
LogError("Failed to send WM_PROGRESS {}", SDL_GetError());
SDL_ClearError();
}
#else
NextCustomEvent.type = static_cast<int>(WM_PROGRESS);
#endif
}
}

Expand All @@ -589,6 +628,10 @@ void ShowProgress(interface_mode uMsg)
ProgressEventHandlerState.done = false;
ProgressEventHandlerState.drawnProgress = 0;

#if !SDL_PUSH_EVENT_BG_THREAD_WORKS
NextCustomEvent.type = -1;
#endif

#ifndef USE_SDL1
DeactivateVirtualGamepad();
FreeVirtualGamepadTextures();
Expand Down Expand Up @@ -623,21 +666,36 @@ void ShowProgress(interface_mode uMsg)
LogVerbose("Load thread finished in {}ms", SDL_GetTicks() - start);
});

const auto processEvent = [&](const SDL_Event &event) {
CheckShouldSkipRendering();
if (event.type != SDL_QUIT) {
HandleMessage(event, SDL_GetModState());
}
if (ProgressEventHandlerState.done) {
loadThread.join();
return false;
}
return true;
};

while (true) {
CheckShouldSkipRendering();
SDL_Event event;
// We use the real `SDL_PollEvent` here instead of `FetchEvent`
// to process real events rather than the recorded ones in demo mode.
while (SDL_PollEvent(&event)) {
CheckShouldSkipRendering();
if (event.type != SDL_QUIT) {
HandleMessage(event, SDL_GetModState());
}
if (ProgressEventHandlerState.done) {
loadThread.join();
return;
if (!processEvent(event)) return;
}
#if !SDL_PUSH_EVENT_BG_THREAD_WORKS
if (const int customEventType = NextCustomEvent.type; customEventType != -1) {
event.type = CustomEventToSdlEvent(static_cast<interface_mode>(customEventType));
if (static_cast<interface_mode>(customEventType) == static_cast<int>(WM_ERROR)) {
event.user.data1 = &NextCustomEvent.error;
}
NextCustomEvent.type = -1;
if (!processEvent(event)) return;
}
#endif
}
}

Expand Down

0 comments on commit dd6d51d

Please sign in to comment.