Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 57 additions & 3 deletions src/window/sdl2/sdl2_display_window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,16 +365,55 @@ void SDL2DisplayWindow::ExitLoop()
ExitRunLoop = true;
}

std::unordered_map<void *, std::function<void()>> SDL2DisplayWindow::Timers;
std::unordered_map<void *, void *> SDL2DisplayWindow::TimerHandles;
unsigned long SDL2DisplayWindow::TimerIDs = 0;
Uint32 TimerEventID = SDL_RegisterEvents(1);

Uint32 SDL2DisplayWindow::ExecTimer(Uint32 interval, void* execID)
{
// cancel event and stop loop if function not found
if (Timers.find(execID) == Timers.end())
return 0;

SDL_Event timerEvent;
SDL_zero(timerEvent);

timerEvent.user.type = TimerEventID;
timerEvent.user.data1 = execID;

SDL_PushEvent(&timerEvent);

return interval;
}

void* SDL2DisplayWindow::StartTimer(int timeoutMilliseconds, std::function<void()> onTimer)
{
// To do: implement timers
CheckInitSDL();

void* execID = (void*)(uintptr_t)++TimerIDs;
void* id = (void*)(uintptr_t)SDL_AddTimer(timeoutMilliseconds, SDL2DisplayWindow::ExecTimer, execID);

if (!id) return id;

Timers.insert({execID, onTimer});
TimerHandles.insert({id, execID});

return nullptr;
return id;
}

void SDL2DisplayWindow::StopTimer(void* timerID)
{
// To do: implement timers
CheckInitSDL();

SDL_RemoveTimer((SDL_TimerID)(uintptr_t)timerID);

auto execID = TimerHandles.find(timerID);
if (execID == TimerHandles.end())
return;

Timers.erase(execID->second);
TimerHandles.erase(timerID);
}

SDL2DisplayWindow* SDL2DisplayWindow::FindEventWindow(const SDL_Event& event)
Expand All @@ -401,6 +440,10 @@ SDL2DisplayWindow* SDL2DisplayWindow::FindEventWindow(const SDL_Event& event)

void SDL2DisplayWindow::DispatchEvent(const SDL_Event& event)
{
// timers are created in a non-window context
if (event.type == TimerEventID)
return OnTimerEvent(event.user);

SDL2DisplayWindow* window = FindEventWindow(event);
if (!window) return;

Expand Down Expand Up @@ -509,6 +552,17 @@ void SDL2DisplayWindow::OnPaintEvent()
WindowHost->OnWindowPaint();
}

void SDL2DisplayWindow::OnTimerEvent(const SDL_UserEvent& event)
{
auto func = Timers.find(event.data1);

// incase timer was cancelled before we get here
if (func == Timers.end())
return;

func->second();
}

InputKey SDL2DisplayWindow::ScancodeToInputKey(SDL_Scancode keycode)
{
switch (keycode)
Expand Down
7 changes: 7 additions & 0 deletions src/window/sdl2/sdl2_display_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class SDL2DisplayWindow : public DisplayWindow
void OnMouseWheel(const SDL_MouseWheelEvent& event);
void OnMouseMotion(const SDL_MouseMotionEvent& event);
void OnPaintEvent();
static void OnTimerEvent(const SDL_UserEvent& event);

InputKey GetMouseButtonKey(const SDL_MouseButtonEvent& event);

Expand All @@ -86,6 +87,7 @@ class SDL2DisplayWindow : public DisplayWindow

static void* StartTimer(int timeoutMilliseconds, std::function<void()> onTimer);
static void StopTimer(void* timerID);
static Uint32 ExecTimer(Uint32 interval, void* id);

DisplayWindowHost* WindowHost = nullptr;
SDL2NativeHandle Handle;
Expand All @@ -102,4 +104,9 @@ class SDL2DisplayWindow : public DisplayWindow
static bool ExitRunLoop;
static Uint32 PaintEventNumber;
static std::unordered_map<int, SDL2DisplayWindow*> WindowList;

static std::unordered_map<void *, void *> TimerHandles;
static std::unordered_map<void *, std::function<void()>> Timers;
static unsigned long TimerIDs;
static Uint32 TimerEventNumber;
};
Loading