Skip to content

Commit

Permalink
windows: use waitable timers
Browse files Browse the repository at this point in the history
  • Loading branch information
eyelash committed Aug 29, 2024
1 parent d6b676a commit 942a0c0
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 42 deletions.
4 changes: 2 additions & 2 deletions demos/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static void mouse_button_press(float x, float y, int button, int modifiers, void
printf("mouse button press: {%f, %f} (modifiers: %X)\n", x, y, modifiers);
struct demo *demo = user_data;
if (demo->timer) {
gral_window_delete_timer(demo->window, demo->timer);
gral_timer_delete(demo->timer);
demo->timer = 0;
}
}
Expand Down Expand Up @@ -126,7 +126,7 @@ static void create_window(void *user_data) {
&focus_leave
};
demo->window = gral_window_create(demo->application, 600, 400, "gral events demo", &interface, demo);
demo->timer = gral_window_create_timer(demo->window, 1000, &timer, demo);
demo->timer = gral_timer_create(1000, &timer, demo);
}

static void open_empty(void *user_data) {
Expand Down
3 changes: 3 additions & 0 deletions gral.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ struct gral_timer *gral_window_create_timer(struct gral_window *window, int mill
void gral_window_delete_timer(struct gral_window *window, struct gral_timer *timer);
void gral_window_run_on_main_thread(struct gral_window *window, void (*callback)(void *user_data), void *user_data);

struct gral_timer *gral_timer_create(int milliseconds, void (*callback)(void *user_data), void *user_data);
void gral_timer_delete(struct gral_timer *timer);


/*=========
FILE
Expand Down
46 changes: 27 additions & 19 deletions gral_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,29 +638,12 @@ void gral_window_clipboard_paste(struct gral_window *window, void (*callback)(ch
gtk_clipboard_request_text(clipboard, paste_callback, callback_data);
}

typedef struct {
void (*callback)(void *user_data);
void *user_data;
} TimerCallbackData;
static gboolean timer_callback(gpointer user_data) {
TimerCallbackData *callback_data = user_data;
callback_data->callback(callback_data->user_data);
return G_SOURCE_CONTINUE;
}
static void timer_destroy(gpointer user_data) {
TimerCallbackData *callback_data = user_data;
g_slice_free(TimerCallbackData, callback_data);
}

struct gral_timer *gral_window_create_timer(struct gral_window *window, int milliseconds, void (*callback)(void *user_data), void *user_data) {
TimerCallbackData *callback_data = g_slice_new(TimerCallbackData);
callback_data->callback = callback;
callback_data->user_data = user_data;
return (struct gral_timer *)(intptr_t)g_timeout_add_full(G_PRIORITY_DEFAULT, milliseconds, timer_callback, callback_data, timer_destroy);
return gral_timer_create(milliseconds, callback, user_data);
}

void gral_window_delete_timer(struct gral_window *window, struct gral_timer *timer) {
g_source_remove((guint)(intptr_t)timer);
gral_timer_delete(timer);
}

typedef struct {
Expand All @@ -682,6 +665,31 @@ void gral_window_run_on_main_thread(struct gral_window *window, void (*callback)
gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE, idle_callback, callback_data, idle_destroy);
}

typedef struct {
void (*callback)(void *user_data);
void *user_data;
} TimerCallbackData;
static gboolean timer_callback(gpointer user_data) {
TimerCallbackData *callback_data = user_data;
callback_data->callback(callback_data->user_data);
return G_SOURCE_CONTINUE;
}
static void timer_destroy(gpointer user_data) {
TimerCallbackData *callback_data = user_data;
g_slice_free(TimerCallbackData, callback_data);
}

struct gral_timer *gral_timer_create(int milliseconds, void (*callback)(void *user_data), void *user_data) {
TimerCallbackData *callback_data = g_slice_new(TimerCallbackData);
callback_data->callback = callback;
callback_data->user_data = user_data;
return (struct gral_timer *)(intptr_t)g_timeout_add_full(G_PRIORITY_DEFAULT, milliseconds, timer_callback, callback_data, timer_destroy);
}

void gral_timer_delete(struct gral_timer *timer) {
g_source_remove((guint)(intptr_t)timer);
}


/*=========
FILE
Expand Down
22 changes: 15 additions & 7 deletions gral_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -679,16 +679,11 @@ - (void)invoke:(NSTimer *)timer {
}
@end
struct gral_timer *gral_window_create_timer(struct gral_window *window, int milliseconds, void (*callback)(void *user_data), void *user_data) {
TimerCallbackObject *callback_object = [[TimerCallbackObject alloc] init];
callback_object->callback = callback;
callback_object->user_data = user_data;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:milliseconds/1000.0 target:callback_object selector:@selector(invoke:) userInfo:nil repeats:YES];
[callback_object release];
return (struct gral_timer *)timer;
return gral_timer_create(milliseconds, callback, user_data);
}

void gral_window_delete_timer(struct gral_window *window, struct gral_timer *timer) {
[(NSTimer *)timer invalidate];
gral_timer_delete(timer);
}

@interface MainThreadCallbackObject: NSObject {
Expand All @@ -710,6 +705,19 @@ void gral_window_run_on_main_thread(struct gral_window *window, void (*callback)
[callback_object release];
}

struct gral_timer *gral_timer_create(int milliseconds, void (*callback)(void *user_data), void *user_data) {
TimerCallbackObject *callback_object = [[TimerCallbackObject alloc] init];
callback_object->callback = callback;
callback_object->user_data = user_data;
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:milliseconds/1000.0 target:callback_object selector:@selector(invoke:) userInfo:nil repeats:YES];
[callback_object release];
return (struct gral_timer *)timer;
}

void gral_timer_delete(struct gral_timer *timer) {
[(NSTimer *)timer invalidate];
}


/*=========
FILE
Expand Down
40 changes: 26 additions & 14 deletions gral_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ struct WindowData {
struct gral_timer {
void (*callback)(void *user_data);
void *user_data;
HANDLE timer;
};


Expand Down Expand Up @@ -458,12 +459,6 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
case WM_KILLFOCUS:
window_data->iface.focus_leave(window_data->user_data);
return 0;
case WM_TIMER:
{
gral_timer *timer = (gral_timer *)wParam;
timer->callback(timer->user_data);
return 0;
}
case WM_SIZE:
{
WORD width = LOWORD(lParam);
Expand Down Expand Up @@ -1065,22 +1060,39 @@ void gral_window_clipboard_paste(gral_window *window, void (*callback)(char cons
}

gral_timer *gral_window_create_timer(gral_window *window, int milliseconds, void (*callback)(void *user_data), void *user_data) {
gral_timer *timer = new gral_timer();
timer->callback = callback;
timer->user_data = user_data;
SetTimer((HWND)window, (UINT_PTR)timer, milliseconds, NULL);
return timer;
return gral_timer_create(milliseconds, callback, user_data);
}

void gral_window_delete_timer(gral_window *window, gral_timer *timer) {
KillTimer((HWND)window, (UINT_PTR)timer);
delete timer;
gral_timer_delete(timer);
}

void gral_window_run_on_main_thread(struct gral_window *window, void (*callback)(void *user_data), void *user_data) {
PostMessage((HWND)window, WM_USER, (WPARAM)callback, (LPARAM)user_data);
}

static void CALLBACK timer_completion_routine(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue) {
gral_timer *timer = (gral_timer *)lpArgToCompletionRoutine;
timer->callback(timer->user_data);
}

gral_timer *gral_timer_create(int milliseconds, void (*callback)(void *user_data), void *user_data) {
gral_timer *timer = new gral_timer();
timer->callback = callback;
timer->user_data = user_data;
timer->timer = CreateWaitableTimer(NULL, FALSE, NULL);
LARGE_INTEGER due_time;
due_time.QuadPart = (LONGLONG)milliseconds * -10000;
SetWaitableTimer(timer->timer, &due_time, milliseconds, &timer_completion_routine, timer, FALSE);
return timer;
}

void gral_timer_delete(gral_timer *timer) {
CancelWaitableTimer(timer->timer);
CloseHandle(timer->timer);
delete timer;
}


/*=========
FILE
Expand Down Expand Up @@ -1206,7 +1218,7 @@ struct gral_directory_watcher {
}
void watch() {
const DWORD notify_filter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_ATTRIBUTES | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_LAST_ACCESS | FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_SECURITY;
ReadDirectoryChangesW(directory, buffer, sizeof(buffer), FALSE, notify_filter, NULL, &overlapped, completion_routine);
ReadDirectoryChangesW(directory, buffer, sizeof(buffer), FALSE, notify_filter, NULL, &overlapped, &completion_routine);
}
void cancel() {
CancelIoEx(directory, &overlapped);
Expand Down

0 comments on commit 942a0c0

Please sign in to comment.