summaryrefslogtreecommitdiff
path: root/guile-osc.c
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2023-04-22 11:07:42 +0200
committerThomas White <taw@physics.org>2023-04-22 11:07:42 +0200
commit5a77730c1a448928f03aba90d0b4e77355d352ed (patch)
tree5a54ba93b2f4953bbe91c355675b2d8f2a42d426 /guile-osc.c
parentbac2dbaeb699fc4e5ebf567f9de02ee957640fc3 (diff)
Add arguments to server methods
Diffstat (limited to 'guile-osc.c')
-rw-r--r--guile-osc.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/guile-osc.c b/guile-osc.c
index af7cd49..c259788 100644
--- a/guile-osc.c
+++ b/guile-osc.c
@@ -88,15 +88,48 @@ struct method_callback_guile_data
lo_arg **argv;
int argc;
lo_message msg;
- void *vp;
+ SCM proc;
};
static void *method_callback_with_guile(void *vp)
{
struct method_callback_guile_data *data = vp;
- struct method_callback_data *mdata = data->vp;
- scm_call_0(mdata->proc);
+ SCM *args;
+
+ if ( data->argc > 0) {
+
+ int i;
+ const char *types;
+
+ args = malloc(sizeof(SCM)*data->argc);
+ if ( args == NULL ) return NULL;
+
+ types = lo_message_get_types(data->msg);
+
+ for ( i=0; i<data->argc; i++ ) {
+ switch ( types[i] ) {
+
+ case 'f':
+ args[i] = scm_from_double(data->argv[i]->f);
+ break;
+
+ case 'i':
+ args[i] = scm_from_int(data->argv[i]->i);
+ break;
+
+ default:
+ fprintf(stderr, "Unrecognised argument type '%c'\n",
+ types[i]);
+ return NULL;
+ }
+ }
+ } else {
+ args = NULL;
+ }
+
+ scm_call_n(data->proc, args, data->argc);
+ free(args);
return NULL;
}
@@ -104,6 +137,8 @@ static void *method_callback_with_guile(void *vp)
static int method_callback(const char *path, const char *types, lo_arg **argv,
int argc, lo_message msg, void *vp)
{
+ struct method_callback_data *data = vp;
+
/* The OSC server thread is not under our control, and is not in
* Guile mode. Therefore, some "tedious mucking-about in hyperspace"
* is required before we can invoke the Scheme callback */
@@ -113,30 +148,35 @@ static int method_callback(const char *path, const char *types, lo_arg **argv,
cb_data.argv = argv;
cb_data.argc = argc;
cb_data.msg = msg;
- cb_data.vp = vp;
+ cb_data.proc = data->proc;
scm_with_guile(method_callback_with_guile, &cb_data);
return 1;
}
-static SCM add_osc_method(SCM server_obj, SCM path_obj, SCM proc)
+static SCM add_osc_method(SCM server_obj, SCM path_obj, SCM argtypes_obj,
+ SCM proc)
{
lo_server_thread srv;
lo_method method;
char *path;
+ char *argtypes;
struct method_callback_data *data;
scm_assert_foreign_object_type(osc_server_thread_type, server_obj);
srv = scm_foreign_object_ref(server_obj, 0);
+ argtypes = scm_to_utf8_stringn(argtypes_obj, NULL);
data = malloc(sizeof(struct method_callback_data));
+
data->proc = proc;
scm_gc_protect_object(proc);
path = scm_to_utf8_stringn(path_obj, NULL);
- method = lo_server_thread_add_method(srv, path, "",
+ method = lo_server_thread_add_method(srv, path, argtypes,
method_callback, data);
free(path);
+ free(argtypes);
return scm_make_foreign_object_1(osc_method_type, method);
}
@@ -195,7 +235,7 @@ void init_guile_osc()
osc_address_type = scm_make_foreign_object_type(name, slots, finalize_osc_address);
scm_c_define_gsubr("make-osc-server-thread", 1, 0, 0, make_osc_server_thread);
- scm_c_define_gsubr("add-osc-method", 3, 0, 0, add_osc_method);
+ scm_c_define_gsubr("add-osc-method", 4, 0, 0, add_osc_method);
scm_c_define_gsubr("make-osc-address", 1, 0, 0, make_osc_address);
scm_c_define_gsubr("osc-send", 2, 0, 1, osc_send);