summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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