From 82be2cce91dc1a7dca7e454959aa8f6e085e0787 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Fri, 11 Sep 2020 14:31:57 -0700 Subject: modules/rtv: make channels set configurable This adds a colon-separated channels setting, with a setting of "all" for the existing all-modules behavior. Colon was used since comma is already taken by the settings separator, maybe in the future comma escaping can be added everywhere relevant but for now just keep it simple. The immediate value of this setting is telling rtv to limit itself to a single module, and using its setting randomizer to automatically observe a variety of the available settings in action on a specific module, especially during development. If knobs ever get added in the future I expect this will become even more interesting for watching specific modules under their various settings permutations in combination with their knobs being twisted - especially if rtv reconstructs random signal generator chains for the "knob-twisters" on every channel switch. An immediately interesting TODO complementing this particular change would be optionally preserving module contexts across channel switches, so when the same module is revisited it resumes where it was last seen. But this conflicts with settings changes on channel switching, since contexts should probably always be recreated when settings change - but that's probably a module-specific detail that modules should just be robust enough to tolerate as in they'd safely ignore settings changes without a context recreate, or apply them if they safely can without a context recreate... TODO. --- src/modules/rtv/rtv.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/modules/rtv/rtv.c b/src/modules/rtv/rtv.c index 704aca6..010e741 100644 --- a/src/modules/rtv/rtv.c +++ b/src/modules/rtv/rtv.c @@ -48,6 +48,7 @@ static int rtv_setup(const settings_t *settings, setting_desc_t **next_setting); static unsigned rtv_duration = RTV_DURATION_SECS; static unsigned rtv_snow_duration = RTV_SNOW_DURATION_SECS; static unsigned rtv_caption_duration = RTV_CAPTION_DURATION_SECS; +static char **rtv_channels; rototiller_module_t rtv_module = { @@ -143,7 +144,7 @@ static void setup_next_module(rtv_context_t *ctxt, unsigned ticks) ctxt->caption = txt_free(ctxt->caption); } - if (ctxt->module != ctxt->snow_module) { + if (!ctxt->n_modules || ctxt->module != ctxt->snow_module) { ctxt->last_module = ctxt->module; ctxt->module = ctxt->snow_module; ctxt->next_switch = now + rtv_snow_duration; @@ -187,6 +188,24 @@ static void setup_next_module(rtv_context_t *ctxt, unsigned ticks) } +static int rtv_skip_module(const rtv_context_t *ctxt, const rototiller_module_t *module) +{ + if (module == &rtv_module || + module == ctxt->snow_module) + return 1; + + if (!rtv_channels) + return 0; + + for (char **channel = rtv_channels; *channel; channel++) { + if (!strcmp(module->name, *channel)) + return 0; + } + + return 1; +} + + static void * rtv_create_context(unsigned ticks, unsigned num_cpus) { rtv_context_t *ctxt; @@ -203,8 +222,7 @@ static void * rtv_create_context(unsigned ticks, unsigned num_cpus) ctxt->snow_module = rototiller_lookup_module("snow"); for (size_t i = 0; i < n_modules; i++) { - if (modules[i] == &rtv_module || - modules[i] == ctxt->snow_module) + if (rtv_skip_module(ctxt, modules[i])) continue; ctxt->modules[ctxt->n_modules++].module = modules[i]; @@ -264,6 +282,23 @@ static int rtv_setup(const settings_t *settings, setting_desc_t **next_setting) const char *duration; const char *caption_duration; const char *snow_duration; + const char *channels; + + channels = settings_get_value(settings, "channels"); + if (!channels) { + int r; + + r = setting_desc_clone(&(setting_desc_t){ + .name = "Colon-Separated List Of Channel Modules", + .key = "channels", + .preferred = "all", + .annotations = NULL + }, next_setting); + if (r < 0) + return r; + + return 1; + } duration = settings_get_value(settings, "duration"); if (!duration) { @@ -316,6 +351,44 @@ static int rtv_setup(const settings_t *settings, setting_desc_t **next_setting) return 1; } + /* turn channels colon-separated list into a null-terminated array of strings */ + if (strcmp(channels, "all")) { + const rototiller_module_t **modules; + size_t n_modules; + char *tokchannels, *channel; + int n = 2; + + rototiller_get_modules(&modules, &n_modules); + + tokchannels = strdup(channels); + if (!tokchannels) + return -ENOMEM; + + channel = strtok(tokchannels, ":"); + do { + char **new; + size_t i; + + for (i = 0; i < n_modules; i++) { + if (!strcmp(channel, modules[i]->name)) + break; + } + + if (i >= n_modules) + return -EINVAL; + + new = realloc(rtv_channels, n * sizeof(*rtv_channels)); + if (!new) + return -ENOMEM; + + new[n - 2] = channel; + new[n - 1] = NULL; + n++; + + rtv_channels = new; + } while (channel = strtok(NULL, ":")); + } + /* TODO FIXME: parse errors */ sscanf(duration, "%u", &rtv_duration); sscanf(caption_duration, "%u", &rtv_caption_duration); -- cgit v1.2.3