I'm just getting started in SDL2 because of the real promise of having portable UI in C#. I'm something of a fan of the idea of one window, one canvas, one event loop anyway. Makes certain things simpler in basic modeling. But that means right now I need to ask very basic questions.
I have a foreground thread that enters the event loop. At some point a background thread needs to tell the foreground thread that application state changed and it needs to redraw something (or everything as the case may be). SDL has application events but I can't figure out how to send them.
void redraw() {
var surface = SDL_GetWindowSurface(window);
SDL_FillRect(surface, IntPtr.Zero, SDL_MapRGB(surface.GetPixelFormat(), 0x9F, 0x9F, 0xFF));
SDL_UpdateWindowSurface(window);
}
new Thread(() => {
Thread.Sleep(30000);
/* SEND EVENT HERE */
}).Start();
bool done = false;
while (!done && SDL_WaitEvent(out var ev) != 0) {
switch (ev.type) {
case SDL_USEREVENT:
redraw();
break;
case SDL_WINDOWEVENT:
switch (ev.window.windowEvent) {
case SDL_WINDOWEVENT_CLOSE:
SDL_DestroyWindow(window);
done = true;
break;
}
break;
}
but I can't find how to send the user event from the other thread.
Don't tell me to use an SDL timer. That's boilerplate. The real code is something else.
So the immediate fix to send the event (BAD CODE ALERT):
new Thread(() => {
Thread.Sleep(30000);
SDL_Event sdlevent = new SDL_Event();
sdlevent.type = SDL_USEREVENT;
SDL_PushEvent(ref sdlevent);
}).Start();
But this code is wrong in case of somebody else registering an event. We need to register an event, get the ID, and use it.
var myevent = (SDL_EventType)SDL_RegisterEvents(1);
new Thread(() => {
Thread.Sleep(30000);
SDL_Event sdlevent = new SDL_Event();
sdlevent.type = myevent;
SDL_PushEvent(ref sdlevent);
}).Start();
And the case
line now reads
case var typemyevent when typemyevent == myevent:
I'm not sure whether to be more embarrassed for C# or SDL for that case line but that's what it is.