Skip to content

Commit

Permalink
decouple gral_run_on_main_thread from the window
Browse files Browse the repository at this point in the history
  • Loading branch information
eyelash committed Sep 2, 2024
1 parent a39503c commit 9a892cd
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 59 deletions.
3 changes: 2 additions & 1 deletion gral.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,12 @@ void gral_window_show_open_file_dialog(struct gral_window *window, void (*callba
void gral_window_show_save_file_dialog(struct gral_window *window, void (*callback)(char const *file, void *user_data), void *user_data);
void gral_window_clipboard_copy(struct gral_window *window, char const *text);
void gral_window_clipboard_paste(struct gral_window *window, void (*callback)(char const *text, void *user_data), void *user_data);
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);

void gral_run_on_main_thread(void (*callback)(void *user_data), void *user_data);


/*=========
FILE
Expand Down
38 changes: 19 additions & 19 deletions gral_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,25 +638,6 @@ 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;
} IdleCallbackData;
static gboolean idle_callback(gpointer user_data) {
IdleCallbackData *callback_data = user_data;
callback_data->callback(callback_data->user_data);
return G_SOURCE_REMOVE;
}
static void idle_destroy(gpointer user_data) {
g_slice_free(IdleCallbackData, user_data);
}
void gral_window_run_on_main_thread(struct gral_window *window, void (*callback)(void *user_data), void *user_data) {
IdleCallbackData *callback_data = g_slice_new(IdleCallbackData);
callback_data->callback = callback;
callback_data->user_data = user_data;
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;
Expand All @@ -682,6 +663,25 @@ void gral_timer_delete(struct gral_timer *timer) {
g_source_remove((guint)(intptr_t)timer);
}

typedef struct {
void (*callback)(void *user_data);
void *user_data;
} IdleCallbackData;
static gboolean idle_callback(gpointer user_data) {
IdleCallbackData *callback_data = user_data;
callback_data->callback(callback_data->user_data);
return G_SOURCE_REMOVE;
}
static void idle_destroy(gpointer user_data) {
g_slice_free(IdleCallbackData, user_data);
}
void gral_run_on_main_thread(void (*callback)(void *user_data), void *user_data) {
IdleCallbackData *callback_data = g_slice_new(IdleCallbackData);
callback_data->callback = callback;
callback_data->user_data = user_data;
gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE, idle_callback, callback_data, idle_destroy);
}


/*=========
FILE
Expand Down
36 changes: 18 additions & 18 deletions gral_macos.m
Original file line number Diff line number Diff line change
Expand Up @@ -667,48 +667,48 @@ void gral_window_clipboard_paste(struct gral_window *window, void (*callback)(ch
}
}

@interface MainThreadCallbackObject: NSObject {
@interface TimerCallbackObject: NSObject {
@public
void (*callback)(void *user_data);
void *user_data;
}
@end
@implementation MainThreadCallbackObject
- (void)invoke:(id)object {
@implementation TimerCallbackObject
- (void)invoke:(NSTimer *)timer {
callback(user_data);
}
@end
void gral_window_run_on_main_thread(struct gral_window *window, void (*callback)(void *user_data), void *user_data) {
MainThreadCallbackObject *callback_object = [[MainThreadCallbackObject alloc] init];

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;
[callback_object performSelectorOnMainThread:@selector(invoke:) withObject:nil waitUntilDone:NO];
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;
}

@interface TimerCallbackObject: NSObject {
void gral_timer_delete(struct gral_timer *timer) {
[(NSTimer *)timer invalidate];
}

@interface MainThreadCallbackObject: NSObject {
@public
void (*callback)(void *user_data);
void *user_data;
}
@end
@implementation TimerCallbackObject
- (void)invoke:(NSTimer *)timer {
@implementation MainThreadCallbackObject
- (void)invoke:(id)object {
callback(user_data);
}
@end

struct gral_timer *gral_timer_create(int milliseconds, void (*callback)(void *user_data), void *user_data) {
TimerCallbackObject *callback_object = [[TimerCallbackObject alloc] init];
void gral_run_on_main_thread(void (*callback)(void *user_data), void *user_data) {
MainThreadCallbackObject *callback_object = [[MainThreadCallbackObject 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 performSelectorOnMainThread:@selector(invoke:) withObject:nil waitUntilDone:NO];
[callback_object release];
return (struct gral_timer *)timer;
}

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


Expand Down
43 changes: 22 additions & 21 deletions gral_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ static ID2D1Factory *factory;
static ID2D1StrokeStyle *stroke_style;
static IWICImagingFactory *imaging_factory;
static IDWriteFactory *dwrite_factory;
static DWORD main_thread_id;

struct gral_draw_context {
ID2D1HwndRenderTarget *target;
Expand Down Expand Up @@ -534,6 +535,7 @@ void gral_application_delete(gral_application *application) {
}

int gral_application_run(gral_application *application, int argc_, char **argv_) {
main_thread_id = GetCurrentThreadId();
int argc;
LPWSTR *argv = CommandLineToArgvW(GetCommandLine(), &argc);
if (argc > 1) {
Expand Down Expand Up @@ -1052,27 +1054,6 @@ void gral_window_clipboard_paste(gral_window *window, void (*callback)(char cons
CloseClipboard();
}

struct MainThreadCallbackData {
void (*callback)(void *user_data);
void *user_data;
};

static void CALLBACK main_thread_completion_routine(ULONG_PTR parameter) {
MainThreadCallbackData *callback_data = (MainThreadCallbackData *)parameter;
callback_data->callback(callback_data->user_data);
delete callback_data;
}

void gral_window_run_on_main_thread(gral_window *window, void (*callback)(void *user_data), void *user_data) {
MainThreadCallbackData *callback_data = new MainThreadCallbackData();
callback_data->callback = callback;
callback_data->user_data = user_data;
DWORD thread_id = GetWindowThreadProcessId((HWND)window, NULL);
HANDLE thread = OpenThread(THREAD_SET_CONTEXT, FALSE, thread_id);
QueueUserAPC(&main_thread_completion_routine, thread, (ULONG_PTR)callback_data);
CloseHandle(thread);
}

static void CALLBACK timer_completion_routine(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, DWORD dwTimerHighValue) {
gral_timer *timer = (gral_timer *)lpArgToCompletionRoutine;
timer->callback(timer->user_data);
Expand All @@ -1095,6 +1076,26 @@ void gral_timer_delete(gral_timer *timer) {
delete timer;
}

struct MainThreadCallbackData {
void (*callback)(void *user_data);
void *user_data;
};

static void CALLBACK main_thread_completion_routine(ULONG_PTR parameter) {
MainThreadCallbackData *callback_data = (MainThreadCallbackData *)parameter;
callback_data->callback(callback_data->user_data);
delete callback_data;
}

void gral_run_on_main_thread(void (*callback)(void *user_data), void *user_data) {
MainThreadCallbackData *callback_data = new MainThreadCallbackData();
callback_data->callback = callback;
callback_data->user_data = user_data;
HANDLE thread = OpenThread(THREAD_SET_CONTEXT, FALSE, main_thread_id);
QueueUserAPC(&main_thread_completion_routine, thread, (ULONG_PTR)callback_data);
CloseHandle(thread);
}


/*=========
FILE
Expand Down

0 comments on commit 9a892cd

Please sign in to comment.