From 1f0853d53d00ec3b1723b49ec44edcbac0d547c8 Mon Sep 17 00:00:00 2001 From: Will Date: Fri, 1 Nov 2024 20:22:16 -0400 Subject: [PATCH] watcher-c: for better ffi, support a ptr-based event callback api --- watcher-c/include/wtr/watcher-c.h | 4 +++ watcher-c/src/test-watcher-c.c | 14 ++++----- watcher-c/src/watcher-c.cpp | 52 +++++++++++++++++++++++++------ 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/watcher-c/include/wtr/watcher-c.h b/watcher-c/include/wtr/watcher-c.h index 8747b0fc..c596bfb4 100644 --- a/watcher-c/include/wtr/watcher-c.h +++ b/watcher-c/include/wtr/watcher-c.h @@ -57,8 +57,12 @@ struct wtr_watcher_event { events and will return nothing. */ typedef void (* wtr_watcher_callback)(struct wtr_watcher_event event, void* context); +typedef void (* wtr_watcher_eventref_callback)(struct wtr_watcher_event* event, void* context); + void* wtr_watcher_open(char const* const path, wtr_watcher_callback callback, void* context); +void* wtr_watcher_open_eventref_stream(char const* const path, wtr_watcher_eventref_callback callback, void* context); + bool wtr_watcher_close(void* watcher); #ifdef __cplusplus diff --git a/watcher-c/src/test-watcher-c.c b/watcher-c/src/test-watcher-c.c index ac95ec1e..26d0dd34 100644 --- a/watcher-c/src/test-watcher-c.c +++ b/watcher-c/src/test-watcher-c.c @@ -4,7 +4,7 @@ #include #include -void callback(struct wtr_watcher_event event, void* data) +void callback(struct wtr_watcher_event* event, void* data) { int* count = (int*)data; *count += 1; @@ -27,11 +27,11 @@ void callback(struct wtr_watcher_event event, void* data) "associated path name: %s\n", #endif *count, - event.path_name, - event.effect_type, - event.path_type, - event.effect_time, - event.associated_path_name ? event.associated_path_name : ""); + event->path_name, + event->effect_type, + event->path_type, + event->effect_time, + event->associated_path_name ? event->associated_path_name : ""); } void do_poll_read_loop(int read_fd) @@ -84,7 +84,7 @@ int main(int argc, char** argv) } if (argc == 3) strncpy(path, argv[2], sizeof(path) - 1); int count = 0; - void* watcher = wtr_watcher_open(path, callback, &count); + void* watcher = wtr_watcher_open_eventref_stream(path, callback, &count); if (! watcher) return 1; getchar(); if (! wtr_watcher_close(watcher)) return 1; diff --git a/watcher-c/src/watcher-c.cpp b/watcher-c/src/watcher-c.cpp index 52101fe8..58c47ae6 100644 --- a/watcher-c/src/watcher-c.cpp +++ b/watcher-c/src/watcher-c.cpp @@ -33,17 +33,13 @@ static int utf16_to_utf8(wchar_t const* utf16_buf, char* utf8_buf, int utf8_buf_ } #endif -void* wtr_watcher_open( - char const* const path, - wtr_watcher_callback callback, - void* context) +#ifndef _WIN32 +inline int make_ev_view(wtr::watcher::event const& ev_owned, wtr_watcher_event& ev_view) +#else +inline int make_ev_view(wtr::watcher::event const& ev_owned, wtr_watcher_event& ev_view, char* path_name, char* associated_path_name) +#endif { - auto wrapped_callback = [callback, context](wtr::watcher::event ev_owned) - { - wtr_watcher_event ev_view = {}; #ifdef _WIN32 - char path_name[PATH_BUF_LEN] = {0}; - char associated_path_name[PATH_BUF_LEN] = {0}; int wp = utf16_to_utf8(ev_owned.path_name.c_str(), path_name, PATH_BUF_LEN); if (wp <= 0) return; ev_view.path_name = path_name; @@ -61,11 +57,49 @@ void* wtr_watcher_open( ev_view.effect_type = (int8_t)ev_owned.effect_type; ev_view.path_type = (int8_t)ev_owned.path_type; ev_view.effect_time = ev_owned.effect_time; + return 0; +} + +void* wtr_watcher_open( + char const* const path, + wtr_watcher_callback callback, + void* context) +{ + auto wrapped_callback = [callback, context](wtr::watcher::event ev_owned) + { + wtr_watcher_event ev_view = {}; +#ifdef _WIN32 + char path_name[PATH_BUF_LEN] = {0}; + char associated_path_name[PATH_BUF_LEN] = {0}; + if (make_ev_view(ev_owned, ev_view, path_name, associated_path_name)) return; +#else + if (make_ev_view(ev_owned, ev_view)) return; +#endif callback(ev_view, context); }; return (void*)new wtr::watcher::watch(path, wrapped_callback); } +void* wtr_watcher_open_eventref_stream( + char const* const path, + wtr_watcher_eventref_callback callback, + void* context) +{ + auto wrapped_callback = [callback, context](wtr::watcher::event ev_owned) + { + wtr_watcher_event ev_view = {}; +#ifdef _WIN32 + char path_name[PATH_BUF_LEN] = {0}; + char associated_path_name[PATH_BUF_LEN] = {0}; + if (make_ev_view(ev_owned, ev_view, path_name, associated_path_name)) return; +#else + if (make_ev_view(ev_owned, ev_view)) return; +#endif + callback(&ev_view, context); + }; + return (void*)new wtr::watcher::watch(path, wrapped_callback); +} + bool wtr_watcher_close(void* watcher) { if (! watcher) return false;