From a16291cc191aab78290dcc42e9773b83e915a8e6 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 9 Jan 2023 18:30:31 -0800 Subject: til_tap: convert taps to intrusive public structs The previous commit implemented taps in a way requiring allocations and cleanup. Let's experiment a bit and just make them absolutely minimal named typed variable+indirection bindings. The helpers are retained, but converted to initializers rather than new() style constructors. They provide type-checking of the variable and indirection pointer, and prevent incorrect TIL_TYPE values going in til_type_t.type for the supplied bound elems+ptr. --- src/Makefile.am | 2 +- src/til_tap.c | 70 ------------------------------------ src/til_tap.h | 108 ++++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 75 insertions(+), 105 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 3b6c0f0..692b56e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = libs modules noinst_LTLIBRARIES = libtil.la -libtil_la_SOURCES = til_args.c til_args.h til_fb.c til_fb.h til_knobs.h til.c til.h til_module_context.c til_module_context.h til_settings.h til_settings.c til_setup.c til_setup.h til_tap.c til_tap.h til_threads.c til_threads.h til_util.c til_util.h +libtil_la_SOURCES = til_args.c til_args.h til_fb.c til_fb.h til_knobs.h til.c til.h til_module_context.c til_module_context.h til_settings.h til_settings.c til_setup.c til_setup.h til_tap.h til_threads.c til_threads.h til_util.c til_util.h libtil_la_CPPFLAGS = -I@top_srcdir@/src libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la modules/compose/libcompose.la modules/drizzle/libdrizzle.la modules/flui2d/libflui2d.la modules/julia/libjulia.la modules/meta2d/libmeta2d.la modules/moire/libmoire.la modules/montage/libmontage.la modules/pixbounce/libpixbounce.la modules/plasma/libplasma.la modules/plato/libplato.la modules/ray/libray.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/snow/libsnow.la modules/sparkler/libsparkler.la modules/spiro/libspiro.la modules/stars/libstars.la modules/strobe/libstrobe.la modules/submit/libsubmit.la modules/swab/libswab.la modules/swarm/libswarm.la modules/voronoi/libvoronoi.la libs/grid/libgrid.la libs/puddle/libpuddle.la libs/ray/libray.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la diff --git a/src/til_tap.c b/src/til_tap.c index 44550b6..e69de29 100644 --- a/src/til_tap.c +++ b/src/til_tap.c @@ -1,70 +0,0 @@ -#include -#include -#include -#include - -#include "til_tap.h" - -/* A "tap" is a named binding of a local variable+pointer to that variable. - * - * It's purpose is to facilitate exposing local variables controlling rendering - * to potential external influence. - * - * While the tap alone does get named, this is mostly for ergonomic reasons since - * it's convenient and natural to name the tap while specifying its variable and - * pointer by name as well. Putting them all in once place. - * - * The tap itself is not a registry or otherwise discoverable entity by itself. - * This is strictly just the local glue, with a name. Other pieces must tie taps - * into streams or settings stuff for addressing them by name at a path or other - * means. - * - * Note the intended way for taps to work is that the caller will always access their - * local variables indirectly via the pointers they provided when creating the taps. - * There will be a function for managing the tap the caller must call before accessing - * the variable indirectly as well. It's that function which will update the indirection - * pointer to potentially point elsewhere if another tap is driving the variable. - */ - -struct til_tap_t { - til_tap_type_t type; - void *ptr; /* points at the caller-provided tap-managed indirection pointer */ - size_t n_elems; /* when > 1, *ptr is an array of n_elems elements. Otherwise individual variable. */ - void *elems; /* points at the first element of type type, may or may not be an array of them */ - char name[]; -}; - - -/* This is the raw tap creator but use the type-checked wrappers in the header and add one if one's missing */ -til_tap_t * til_tap_new(til_tap_type_t type, void *ptr, const char *name, size_t n_elems, void *elems) -{ - til_tap_t *tap; - - assert(name); - assert(type < TIL_TAP_TYPE_MAX); - assert(ptr); - assert(n_elems); - assert(elems); - - tap = calloc(1, sizeof(til_tap_t) + strlen(name) + 1); - if (!tap) - return NULL; - - strcpy(tap->name, name); - tap->type = type; - tap->ptr = ptr; - tap->n_elems = n_elems; - tap->elems = elems; - - *((void **)tap->ptr) = elems; - - return tap; -} - - -til_tap_t * til_tap_free(til_tap_t *tap) -{ - free(tap); - - return NULL; -} diff --git a/src/til_tap.h b/src/til_tap.h index b9de6d9..a6384de 100644 --- a/src/til_tap.h +++ b/src/til_tap.h @@ -3,6 +3,23 @@ #include +/* A "tap" is a named binding of a local variable+pointer to that variable. + * + * Its purpose is to facilitate exposing local variables controlling rendering + * to potential external influence. + * + * The tap itself is not a registry or otherwise discoverable entity by itself. + * This is strictly just the local glue, Other pieces must index and tie taps + * into streams or settings stuff for addressing them by name at a path or other + * means. + * + * Note the intended way for taps to work is that the caller will always access their + * local variables indirectly via the pointers they provided when initializing the taps. + * There will be a function for managing the tap the caller must call before accessing + * the variable indirectly as well. It's that function which will update the indirection + * pointer to potentially point elsewhere if another tap is driving the variable. + */ + /* These are all the supported tap types, nothing is set in stone this just * seemed like the likely stuff to need. Feel free to add anything as needed. */ @@ -25,10 +42,14 @@ typedef enum til_tap_type_t { TIL_TAP_TYPE_MAX, } til_tap_type_t; -typedef struct til_tap_t til_tap_t; - -til_tap_t * til_tap_new(til_tap_type_t type, void *ptr, const char *name, size_t n_elems, void *elems); -til_tap_t * til_tap_free(til_tap_t *tap); +/* this is deliberately left entirely public so taps can be easily embedded in contexts */ +typedef struct til_tap_t { + til_tap_type_t type; + void *ptr; /* points at the caller-provided tap-managed indirection pointer */ + size_t n_elems; /* when > 1, *ptr is an array of n_elems elements. Otherwise individual variable. */ + void *elems; /* points at the first element of type type, may or may not be an array of them */ + const char *name; +} til_tap_t; /* just some forward declared higher-order vector and matrix types for the wrappers */ typedef struct v2f_t v2f_t; @@ -36,82 +57,101 @@ typedef struct v3f_t v3f_t; typedef struct v4f_t v4f_t; typedef struct m4f_t m4f_t; +/* This is the bare tap initializer but use the type-checked wrappers below and add one if one's missing */ +static inline void til_tap_init(til_tap_t *tap, til_tap_type_t type, void *ptr, size_t n_elems, void *elems, const char *name) +{ + assert(tap); + assert(type < TIL_TAP_TYPE_MAX); + assert(ptr); + assert(n_elems); + assert(elems); + assert(name); + + tap->type = type; + tap->ptr = ptr; + tap->n_elems = n_elems; + tap->elems = elems; + tap->name = name; + + *((void **)tap->ptr) = elems; +} + /* typed wrappers, just supply n_elems=1 for individual variables - note n_elems is just a defensive * programming sanity check to catch callers mismatching array sizes */ -static inline til_tap_t * til_tap_new_i8(int8_t **ptr, const char *name, size_t n_elems, int8_t *elems) +static inline void til_tap_init_i8(til_tap_t *tap, int8_t **ptr, size_t n_elems, int8_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_I8, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_I8, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_i16(int16_t **ptr, const char *name, size_t n_elems, int16_t *elems) +static inline void til_tap_init_i16(til_tap_t *tap, int16_t **ptr, size_t n_elems, int16_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_I16, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_I16, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_i32(int32_t **ptr, const char *name, size_t n_elems, int32_t *elems) +static inline void til_tap_init_i32(til_tap_t *tap, int32_t **ptr, size_t n_elems, int32_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_I32, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_I32, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_i64(int64_t **ptr, const char *name, size_t n_elems, int64_t *elems) +static inline void til_tap_init_i64(til_tap_t *tap, int64_t **ptr, size_t n_elems, int64_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_I64, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_I64, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_u8(uint8_t **ptr, const char *name, size_t n_elems, uint8_t *elems) +static inline void til_tap_init_u8(til_tap_t *tap, uint8_t **ptr, size_t n_elems, uint8_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_U8, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_U8, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_u16(uint16_t **ptr, const char *name, size_t n_elems, uint16_t *elems) +static inline void til_tap_init_u16(til_tap_t *tap, uint16_t **ptr, size_t n_elems, uint16_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_U16, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_U16, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_u32(uint32_t **ptr, const char *name, size_t n_elems, uint32_t *elems) +static inline void til_tap_init_u32(til_tap_t *tap, uint32_t **ptr, size_t n_elems, uint32_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_U32, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_U32, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_u64(uint64_t **ptr, const char *name, size_t n_elems, uint64_t *elems) +static inline void til_tap_init_u64(til_tap_t *tap, uint64_t **ptr, size_t n_elems, uint64_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_U64, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_U64, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_float(float **ptr, const char *name, size_t n_elems, float *elems) +static inline void til_tap_init_float(til_tap_t *tap, float **ptr, size_t n_elems, float *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_FLOAT, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_FLOAT, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_double(double **ptr, const char *name, size_t n_elems, double *elems) +static inline void til_tap_init_double(til_tap_t *tap, double **ptr, size_t n_elems, double *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_DOUBLE, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_DOUBLE, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_v2f(v2f_t **ptr, const char *name, size_t n_elems, v2f_t *elems) +static inline void til_tap_init_v2f(til_tap_t *tap, v2f_t **ptr, size_t n_elems, v2f_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_V2F, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_V2F, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_v3f(v3f_t **ptr, const char *name, size_t n_elems, v3f_t *elems) +static inline void til_tap_init_v3f(til_tap_t *tap, v3f_t **ptr, size_t n_elems, v3f_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_V3F, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_V3F, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_v4f(v4f_t **ptr, const char *name, size_t n_elems, v4f_t *elems) +static inline void til_tap_init_v4f(til_tap_t *tap, v4f_t **ptr, size_t n_elems, v4f_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_V4F, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_V4F, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_m4f(m4f_t **ptr, const char *name, size_t n_elems, m4f_t *elems) +static inline void til_tap_init_m4f(til_tap_t *tap, m4f_t **ptr, size_t n_elems, m4f_t *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_M4F, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_M4F, ptr, n_elems, elems, name); } -static inline til_tap_t * til_tap_new_voidp(void **ptr, const char *name, size_t n_elems, void *elems) +static inline void til_tap_init_voidp(til_tap_t *tap, void **ptr, size_t n_elems, void *elems, const char *name) { - return til_tap_new(TIL_TAP_TYPE_VOIDP, ptr, name, n_elems, elems); + return til_tap_init(tap, TIL_TAP_TYPE_VOIDP, ptr, n_elems, elems, name); } #endif -- cgit v1.2.1