diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2023-08-05 11:11:14 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2023-08-05 11:11:14 -0700 |
commit | 1a6210be32d6b96483f595e30ad3ae1ef5ebd58b (patch) | |
tree | 4deff90d551b73ce61b79f0ed57b5e74082b038d | |
parent | de6297c0c809d742d6d6c105bbbcb31187c64a14 (diff) |
til: make builtins first-class modules w/new flag
Also move builtins to a separate listing while at it
For now this results in the builtins showing up in the modules
list alongside the actual rendering modules. Future work must
refine this UX, maybe by adding some metadata to the spec.values
for categorizing/prioritizing what's shown always vs. what's
present but hidden without asking to be shown hidden stuff or
whatever.
Just consolidating some junk and working towards every nested
module setup going through the same machinery, and always being
able to access the builtins.
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/til.c | 198 | ||||
-rw-r--r-- | src/til.h | 1 | ||||
-rw-r--r-- | src/til_builtins.c | 167 |
4 files changed, 183 insertions, 185 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 094f295..fee59f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,7 @@ SUBDIRS = libs modules noinst_LTLIBRARIES = libtil.la -libtil_la_SOURCES = til.c til.h til_args.c til_args.h til_fb.c til_fb.h til_jenkins.c til_jenkins.h til_limits.h til_module_context.c til_module_context.h til_settings.h til_settings.c til_setup.c til_setup.h til_str.c til_str.h til_stream.c til_stream.h til_tap.h til_threads.c til_threads.h til_util.c til_util.h +libtil_la_SOURCES = til.c til.h til_args.c til_args.h til_builtins.c til_fb.c til_fb.h til_jenkins.c til_jenkins.h til_limits.h til_module_context.c til_module_context.h til_settings.h til_settings.c til_setup.c til_setup.h til_str.c til_str.h til_stream.c til_stream.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/mixer/libmixer.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/rkt/librkt.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/signals/libsignals.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/rocket/librocket.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la @@ -57,6 +57,11 @@ extern til_module_t swab_module; extern til_module_t swarm_module; extern til_module_t voronoi_module; +/* built-ins (til_builtins.c) */ +extern til_module_t _blank_module; +extern til_module_t _noop_module; +extern til_module_t _ref_module; + static const til_module_t *modules[] = { &blinds_module, &checkers_module, @@ -86,6 +91,11 @@ static const til_module_t *modules[] = { &swab_module, &swarm_module, &voronoi_module, + + /* built-ins at the end */ + &_blank_module, + &_noop_module, + &_ref_module, }; @@ -143,193 +153,13 @@ unsigned til_ticks_now(void) } -/* "blank" built-in module */ -static void _blank_prepare_frame(til_module_context_t *context, til_stream_t *stream, unsigned ticks, til_fb_fragment_t **fragment_ptr, til_frame_plan_t *res_frame_plan) -{ - *res_frame_plan = (til_frame_plan_t){ .fragmenter = til_fragmenter_slice_per_cpu }; -} - - -static void _blank_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr) -{ - til_fb_fragment_clear(*fragment_ptr); -} - - -static til_module_t _blank_module = { - .prepare_frame = _blank_prepare_frame, - .render_fragment = _blank_render_fragment, - .name = "blank", - .description = "built-in blanker", - .author = "built-in", -}; - - -/* "noop" built-in module */ -static til_module_t _noop_module = { - .name = "noop", - .description = "built-in nothing-doer", - .author = "built-in", -}; - - -/* "ref" built-in module */ -#include "libs/txt/txt.h" /* for rendering some diagnostics */ - -typedef struct _ref_setup_t { - til_setup_t til_setup; - - char *path; -} _ref_setup_t; - - -typedef struct _ref_context_t { - til_module_context_t til_module_context; - - til_module_context_t *ref; -} _ref_context_t; - - -static til_module_context_t * _ref_create_context(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup) -{ - _ref_context_t *ctxt; - - ctxt = til_module_context_new(module, sizeof(*ctxt), stream, seed, ticks, n_cpus, setup); - if (!ctxt) - return NULL; - - return &ctxt->til_module_context; -} - - -static void _ref_destroy_context(til_module_context_t *context) -{ - _ref_context_t *ctxt = (_ref_context_t *)context; - - ctxt->ref = til_module_context_free(ctxt->ref); - free(context); -} - - -static void _ref_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr) -{ - _ref_context_t *ctxt = (_ref_context_t *)context; - _ref_setup_t *s = (_ref_setup_t *)context->setup; - - if (!ctxt->ref) { - int r; - - /* TODO: switch to til_stream_find_module_context(), this clones concept is DOA. */ - r = til_stream_find_module_contexts(stream, s->path, 1, &ctxt->ref); - if (r < 0) { - txt_t *msg = txt_newf("%s: BAD PATH \"%s\"", context->setup->path, s->path); - - til_fb_fragment_clear(*fragment_ptr); - txt_render_fragment(msg, *fragment_ptr, 0xffffffff, - 0, 0, - (txt_align_t){ - .horiz = TXT_HALIGN_LEFT, - .vert = TXT_VALIGN_TOP, - }); - txt_free(msg); - /* TODO: maybe print all available contexts into the fragment? */ - return; - } - } - - til_module_render_limited(ctxt->ref, stream, ticks, context->n_cpus, fragment_ptr); -} - - -static void _ref_setup_free(til_setup_t *setup) -{ - _ref_setup_t *s = (_ref_setup_t *)setup; - - free(s->path); - free(s); -} - - -static int _ref_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup); - - -static til_module_t _ref_module = { - .create_context = _ref_create_context, - .destroy_context = _ref_destroy_context, - .render_fragment = _ref_render_fragment, - .setup = _ref_setup, - .name = "ref", - .description = "built-in context referencer", - .author = "built-in", -}; - - -static int _ref_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup) -{ - const char *path; - int r; - - r = til_settings_get_and_describe_value(settings, - &(til_setting_spec_t){ - .name = "Context path to reference", - .key = "path", - .regex = "[a-zA-Z0-9/_]+", - .preferred = "", - }, - &path, - res_setting, - res_desc); - if (r) - return r; - - if (res_setup) { - _ref_setup_t *setup; - - setup = til_setup_new(settings, sizeof(*setup), _ref_setup_free, &_ref_module); - if (!setup) - return -ENOMEM; - - setup->path = strdup(path); - if (!setup->path) { - til_setup_free(&setup->til_setup); - - return -ENOMEM; - } - - *res_setup = &setup->til_setup; - } - - return 0; -} - - const til_module_t * til_lookup_module(const char *name) { - static const til_module_t *builtins[] = { - &_blank_module, - &_noop_module, - &_ref_module, - }; - static struct { - const til_module_t **modules; - size_t n_modules; - } module_lists[] = { - { - builtins, - nelems(builtins), - }, - { modules, - nelems(modules), - } - }; - assert(name); - for (size_t n = 0; n < nelems(module_lists); n++) { - for (size_t i = 0; i < module_lists[n].n_modules; i++) { - if (!strcasecmp(name, module_lists[n].modules[i]->name)) - return module_lists[n].modules[i]; - } + for (size_t i = 0; i < nelems(modules); i++) { + if (!strcasecmp(name, modules[i]->name)) + return modules[i]; } return NULL; @@ -615,7 +445,7 @@ int til_module_setup(const til_settings_t *settings, til_setting_t **res_setting res_setting, res_desc, res_setup, - "Renderer Module", + "Renderer module", parent ? TIL_DEFAULT_NESTED_MODULE : TIL_DEFAULT_ROOT_MODULE, (TIL_MODULE_EXPERIMENTAL | (parent ? TIL_MODULE_HERMETIC : 0)), NULL); @@ -23,6 +23,7 @@ typedef struct til_stream_t til_stream_t; #define TIL_MODULE_OVERLAYABLE 1u /* module is appropriate for overlay use */ #define TIL_MODULE_HERMETIC 2u /* module doesn't work readily with other modules / requires manual settings */ #define TIL_MODULE_EXPERIMENTAL 4u /* module is buggy / unfinished */ +#define TIL_MODULE_BUILTIN 8u /* module is implements "built-in" libtil functionality not intended to be interesting by itself */ struct til_module_t { til_module_context_t * (*create_context)(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup); diff --git a/src/til_builtins.c b/src/til_builtins.c new file mode 100644 index 0000000..7a36d23 --- /dev/null +++ b/src/til_builtins.c @@ -0,0 +1,167 @@ +#include "til.h" +#include "til_fb.h" +#include "til_module_context.h" +#include "til_settings.h" +#include "til_stream.h" + +#include "libs/txt/txt.h" /* for rendering some diagnostics (ref built-in)) */ + + +/* "blank" built-in module */ +static void _blank_prepare_frame(til_module_context_t *context, til_stream_t *stream, unsigned ticks, til_fb_fragment_t **fragment_ptr, til_frame_plan_t *res_frame_plan) +{ + *res_frame_plan = (til_frame_plan_t){ .fragmenter = til_fragmenter_slice_per_cpu }; +} + + +static void _blank_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr) +{ + til_fb_fragment_clear(*fragment_ptr); +} + + +til_module_t _blank_module = { + .prepare_frame = _blank_prepare_frame, + .render_fragment = _blank_render_fragment, + .name = "blank", + .description = "Blanker (built-in)", + .author = "built-in", +}; + + +/* "noop" built-in module */ +til_module_t _noop_module = { + .name = "noop", + .description = "Nothing-doer (built-in)", + .author = "built-in", + .flags = TIL_MODULE_BUILTIN, +}; + + +/* "ref" built-in module */ +typedef struct _ref_setup_t { + til_setup_t til_setup; + + char *path; +} _ref_setup_t; + + +typedef struct _ref_context_t { + til_module_context_t til_module_context; + + til_module_context_t *ref; +} _ref_context_t; + + +static til_module_context_t * _ref_create_context(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup) +{ + _ref_context_t *ctxt; + + ctxt = til_module_context_new(module, sizeof(*ctxt), stream, seed, ticks, n_cpus, setup); + if (!ctxt) + return NULL; + + return &ctxt->til_module_context; +} + + +static void _ref_destroy_context(til_module_context_t *context) +{ + _ref_context_t *ctxt = (_ref_context_t *)context; + + ctxt->ref = til_module_context_free(ctxt->ref); + free(context); +} + + +static void _ref_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr) +{ + _ref_context_t *ctxt = (_ref_context_t *)context; + _ref_setup_t *s = (_ref_setup_t *)context->setup; + + if (!ctxt->ref) { + int r; + + /* TODO: switch to til_stream_find_module_context(), this clones concept is DOA. */ + r = til_stream_find_module_contexts(stream, s->path, 1, &ctxt->ref); + if (r < 0) { + txt_t *msg = txt_newf("%s: BAD PATH \"%s\"", context->setup->path, s->path); + + til_fb_fragment_clear(*fragment_ptr); + txt_render_fragment(msg, *fragment_ptr, 0xffffffff, + 0, 0, + (txt_align_t){ + .horiz = TXT_HALIGN_LEFT, + .vert = TXT_VALIGN_TOP, + }); + txt_free(msg); + /* TODO: maybe print all available contexts into the fragment? */ + return; + } + } + + til_module_render_limited(ctxt->ref, stream, ticks, context->n_cpus, fragment_ptr); +} + + +static void _ref_setup_free(til_setup_t *setup) +{ + _ref_setup_t *s = (_ref_setup_t *)setup; + + free(s->path); + free(s); +} + + +static int _ref_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup); + + +til_module_t _ref_module = { + .create_context = _ref_create_context, + .destroy_context = _ref_destroy_context, + .render_fragment = _ref_render_fragment, + .setup = _ref_setup, + .name = "ref", + .description = "Context referencer (built-in)", + .author = "built-in", + .flags = TIL_MODULE_BUILTIN, +}; + + +static int _ref_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup) +{ + const char *path; + int r; + + r = til_settings_get_and_describe_value(settings, + &(til_setting_spec_t){ + .name = "Context path to reference", + .key = "path", + .regex = "[a-zA-Z0-9/_]+", + .preferred = "", + }, + &path, + res_setting, + res_desc); + if (r) + return r; + + if (res_setup) { + _ref_setup_t *setup; + + setup = til_setup_new(settings, sizeof(*setup), _ref_setup_free, &_ref_module); + if (!setup) + return -ENOMEM; + + setup->path = strdup(path); + if (!setup->path) { + til_setup_free(&setup->til_setup); + + return -ENOMEM; + } + + *res_setup = &setup->til_setup; + } + + return 0; +} |