summaryrefslogtreecommitdiff
path: root/src/modules/rtv
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-09-12 19:50:56 -0700
committerVito Caputo <vcaputo@pengaru.com>2020-09-12 19:50:56 -0700
commit44b32d60501cc5320de4b34d34c9de3d5f4c11bf (patch)
tree051d3289c4ecce2146d5785b0619c6c5f606da0b /src/modules/rtv
parentc829689a9b285db0243880d020a727f664d41e74 (diff)
modules/rtv: implement context_duration setting
This renames rtv_channel_t to rtv_module_t and modules to channels in various places, which arguably should have been in a separate commit but I'm not up for separating that out at the moment. Fundamentally what's happening is every channel is getting its own context which may persist across channel switches, this allows watching a variety of channels in a stateful manner before they get their contexts recreated with re-randomized settings. For modules without settings it's not terribly interesting, and I'm thinking modules should probably start deriving some of their state more directly from the global ticks rather than their own per-context counters and timers. That way even when their contexts get recreated with re-randomized settings, there can be some continuity for ticks-derived state. Deriving position for instance mathematically from ticks would allow things to be located continuously despite having their contexts and even settings changed, which may be interesting. Anyhow, if you want the previous behavior where contexts are always recreated on channel switch, just set the value to be contxt_duration equal to duration.
Diffstat (limited to 'src/modules/rtv')
-rw-r--r--src/modules/rtv/rtv.c144
1 files changed, 93 insertions, 51 deletions
diff --git a/src/modules/rtv/rtv.c b/src/modules/rtv/rtv.c
index be974d1..3aaad65 100644
--- a/src/modules/rtv/rtv.c
+++ b/src/modules/rtv/rtv.c
@@ -18,27 +18,31 @@
#define RTV_SNOW_DURATION_SECS 1
#define RTV_DURATION_SECS 15
#define RTV_CAPTION_DURATION_SECS 5
+#define RTV_CONTEXT_DURATION_SECS 60
-typedef struct rtv_module_t {
+typedef struct rtv_channel_t {
const rototiller_module_t *module;
+ void *module_ctxt;
+ time_t last_on_time, cumulative_time;
+ char *settings;
+ txt_t *caption;
unsigned order;
-} rtv_module_t;
+} rtv_channel_t;
typedef struct rtv_context_t {
unsigned n_cpus;
time_t next_switch, next_hide_caption;
- const rototiller_module_t *module, *last_module;
- void *module_ctxt;
+ rtv_channel_t *channel, *last_channel;
txt_t *caption;
- const rototiller_module_t *snow_module;
+ rtv_channel_t snow_channel;
- size_t n_modules;
- rtv_module_t modules[];
+ size_t n_channels;
+ rtv_channel_t channels[];
} rtv_context_t;
-static void setup_next_module(rtv_context_t *ctxt, unsigned ticks);
+static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks);
static void * rtv_create_context(unsigned ticks, unsigned num_cpus);
static void rtv_destroy_context(void *context);
static void rtv_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter);
@@ -46,6 +50,7 @@ static void rtv_finish_frame(void *context, unsigned ticks, fb_fragment_t *fragm
static int rtv_setup(const settings_t *settings, setting_desc_t **next_setting);
static unsigned rtv_duration = RTV_DURATION_SECS;
+static unsigned rtv_context_duration = RTV_CONTEXT_DURATION_SECS;
static unsigned rtv_snow_duration = RTV_SNOW_DURATION_SECS;
static unsigned rtv_caption_duration = RTV_CAPTION_DURATION_SECS;
static char **rtv_channels;
@@ -64,26 +69,26 @@ rototiller_module_t rtv_module = {
};
-static int cmp_modules(const void *p1, const void *p2)
+static int cmp_channels(const void *p1, const void *p2)
{
- const rtv_module_t *m1 = p1, *m2 = p2;
+ const rtv_channel_t *c1 = p1, *c2 = p2;
- if (m1->order < m2->order)
+ if (c1->order < c2->order)
return -1;
- if (m1->order > m2->order)
+ if (c1->order > c2->order)
return 1;
return 0;
}
-static void randomize_modules(rtv_context_t *ctxt)
+static void randomize_channels(rtv_context_t *ctxt)
{
- for (size_t i = 0; i < ctxt->n_modules; i++)
- ctxt->modules[i].order = rand();
+ for (size_t i = 0; i < ctxt->n_channels; i++)
+ ctxt->channels[i].order = rand();
- qsort(ctxt->modules, ctxt->n_modules, sizeof(rtv_module_t), cmp_modules);
+ qsort(ctxt->channels, ctxt->n_channels, sizeof(rtv_channel_t), cmp_channels);
}
@@ -129,69 +134,84 @@ static char * randomize_module_setup(const rototiller_module_t *module)
}
-static void setup_next_module(rtv_context_t *ctxt, unsigned ticks)
+static void setup_next_channel(rtv_context_t *ctxt, unsigned ticks)
{
time_t now = time(NULL);
/* TODO: most of this module stuff should probably be
* in rototiller.c helpers, but it's harmless for now.
*/
- if (ctxt->module) {
- if (ctxt->module->destroy_context)
- ctxt->module->destroy_context(ctxt->module_ctxt);
+ if (ctxt->channel) {
+ ctxt->channel->cumulative_time += now - ctxt->channel->last_on_time;
+ if (ctxt->channel->cumulative_time >= rtv_context_duration) {
+ ctxt->channel->cumulative_time = 0;
+
+ if (ctxt->channel->module->destroy_context)
+ ctxt->channel->module->destroy_context(ctxt->channel->module_ctxt);
+ ctxt->channel->module_ctxt = NULL;
+
+ free(ctxt->channel->settings);
+ ctxt->channel->settings = NULL;
- ctxt->module_ctxt = NULL;
- ctxt->caption = txt_free(ctxt->caption);
+ ctxt->caption = ctxt->channel->caption = txt_free(ctxt->channel->caption);
+ }
}
- if (!ctxt->n_modules || ctxt->module != ctxt->snow_module) {
- ctxt->last_module = ctxt->module;
- ctxt->module = ctxt->snow_module;
+ if (!ctxt->n_channels || ctxt->channel != &ctxt->snow_channel) {
+ ctxt->last_channel = ctxt->channel;
+ ctxt->channel = &ctxt->snow_channel;
+ ctxt->caption = NULL;
ctxt->next_switch = now + rtv_snow_duration;
} else {
- char *setup;
size_t i;
- for (i = 0; i < ctxt->n_modules; i++) {
- if (ctxt->modules[i].module == ctxt->last_module) {
+ for (i = 0; i < ctxt->n_channels; i++) {
+ if (&ctxt->channels[i] == ctxt->last_channel) {
i++;
break;
}
}
- if (i >= ctxt->n_modules) {
- randomize_modules(ctxt);
- ctxt->last_module = NULL;
+ if (i >= ctxt->n_channels) {
+ randomize_channels(ctxt);
+ ctxt->last_channel = NULL;
i = 0;
}
- ctxt->module = ctxt->modules[i].module;
+ ctxt->channel = &ctxt->channels[i];
- setup = randomize_module_setup(ctxt->module);
+ if (!ctxt->channel->settings) {
+ char *settings;
+ txt_t *caption;
- ctxt->caption = txt_newf("Title: %s\nAuthor: %s\nDescription: %s\nLicense: %s%s%s",
- ctxt->module->name,
- ctxt->module->author,
- ctxt->module->description,
- ctxt->module->license,
- setup ? "\nSettings: " : "",
- setup ? setup : "");
+ settings = randomize_module_setup(ctxt->channel->module);
+ caption = txt_newf("Title: %s\nAuthor: %s\nDescription: %s\nLicense: %s%s%s",
+ ctxt->channel->module->name,
+ ctxt->channel->module->author,
+ ctxt->channel->module->description,
+ ctxt->channel->module->license,
+ settings ? "\nSettings: " : "",
+ settings ? settings : "");
- free(setup);
+ ctxt->caption = ctxt->channel->caption = caption;
+ ctxt->channel->settings = settings ? settings : strdup("");
+ }
ctxt->next_switch = now + rtv_duration;
ctxt->next_hide_caption = now + rtv_caption_duration;
}
- if (ctxt->module->create_context)
- ctxt->module_ctxt = ctxt->module->create_context(ticks, ctxt->n_cpus);
+ if (!ctxt->channel->module_ctxt && ctxt->channel->module->create_context)
+ ctxt->channel->module_ctxt = ctxt->channel->module->create_context(ticks, ctxt->n_cpus);
+
+ ctxt->channel->last_on_time = now;
}
static int rtv_should_skip_module(const rtv_context_t *ctxt, const rototiller_module_t *module)
{
if (module == &rtv_module ||
- module == ctxt->snow_module)
+ module == ctxt->snow_channel.module)
return 1;
if (!rtv_channels)
@@ -214,21 +234,24 @@ static void * rtv_create_context(unsigned ticks, unsigned num_cpus)
rototiller_get_modules(&modules, &n_modules);
- ctxt = calloc(1, sizeof(rtv_context_t) + n_modules * sizeof(rtv_module_t));
+ ctxt = calloc(1, sizeof(rtv_context_t) + n_modules * sizeof(rtv_channel_t));
if (!ctxt)
return NULL;
ctxt->n_cpus = num_cpus;
- ctxt->snow_module = rototiller_lookup_module("snow");
+
+ ctxt->snow_channel.module = rototiller_lookup_module("snow");
+ if (ctxt->snow_channel.module->create_context)
+ ctxt->snow_channel.module_ctxt = ctxt->snow_channel.module->create_context(ticks, ctxt->n_cpus);
for (size_t i = 0; i < n_modules; i++) {
if (rtv_should_skip_module(ctxt, modules[i]))
continue;
- ctxt->modules[ctxt->n_modules++].module = modules[i];
+ ctxt->channels[ctxt->n_channels++].module = modules[i];
}
- setup_next_module(ctxt, ticks);
+ setup_next_channel(ctxt, ticks);
return ctxt;
}
@@ -246,12 +269,12 @@ static void rtv_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb
time_t now = time(NULL);
if (now >= ctxt->next_switch)
- setup_next_module(ctxt, ticks);
+ setup_next_channel(ctxt, ticks);
if (now >= ctxt->next_hide_caption)
- ctxt->caption = txt_free(ctxt->caption);
+ ctxt->caption = NULL;
- rototiller_module_render(ctxt->module, ctxt->module_ctxt, ticks, fragment);
+ rototiller_module_render(ctxt->channel->module, ctxt->channel->module_ctxt, ticks, fragment);
}
@@ -280,6 +303,7 @@ static void rtv_finish_frame(void *context, unsigned ticks, fb_fragment_t *fragm
static int rtv_setup(const settings_t *settings, setting_desc_t **next_setting)
{
const char *duration;
+ const char *context_duration;
const char *caption_duration;
const char *snow_duration;
const char *channels;
@@ -317,6 +341,23 @@ static int rtv_setup(const settings_t *settings, setting_desc_t **next_setting)
return 1;
}
+ context_duration = settings_get_value(settings, "context_duration");
+ if (!context_duration) {
+ int r;
+
+ r = setting_desc_clone(&(setting_desc_t){
+ .name = "Context Duration In Seconds",
+ .key = "context_duration",
+ .regex = "\\.[0-9]+",
+ .preferred = SETTINGS_STR(RTV_CONTEXT_DURATION_SECS),
+ .annotations = NULL
+ }, next_setting);
+ if (r < 0)
+ return r;
+
+ return 1;
+ }
+
caption_duration = settings_get_value(settings, "caption_duration");
if (!caption_duration) {
int r;
@@ -391,6 +432,7 @@ static int rtv_setup(const settings_t *settings, setting_desc_t **next_setting)
/* TODO FIXME: parse errors */
sscanf(duration, "%u", &rtv_duration);
+ sscanf(context_duration, "%u", &rtv_context_duration);
sscanf(caption_duration, "%u", &rtv_caption_duration);
sscanf(snow_duration, "%u", &rtv_snow_duration);
© All Rights Reserved