Skip to content

Commit

Permalink
watcher-c: for better ffi, support a ptr-based event callback api
Browse files Browse the repository at this point in the history
  • Loading branch information
Will committed Nov 2, 2024
1 parent fcbd521 commit 1f0853d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 16 deletions.
4 changes: 4 additions & 0 deletions watcher-c/include/wtr/watcher-c.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions watcher-c/src/test-watcher-c.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <unistd.h>
#include <poll.h>

void callback(struct wtr_watcher_event event, void* data)
void callback(struct wtr_watcher_event* event, void* data)
{
int* count = (int*)data;
*count += 1;
Expand All @@ -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)
Expand Down Expand Up @@ -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;
Expand Down
52 changes: 43 additions & 9 deletions watcher-c/src/watcher-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 1f0853d

Please sign in to comment.