summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/til.c136
1 files changed, 133 insertions, 3 deletions
diff --git a/src/til.c b/src/til.c
index 4241c12..5a9a964 100644
--- a/src/til.c
+++ b/src/til.c
@@ -16,6 +16,7 @@
#include "til_fb.h"
#include "til_module_context.h"
#include "til_settings.h"
+#include "til_stream.h"
#include "til_threads.h"
#include "til_util.h"
@@ -107,6 +108,7 @@ void til_shutdown(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 };
@@ -128,11 +130,139 @@ static til_module_t _blank_module = {
};
+/* "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(ctxt->ref, stream, ticks, 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)
+{
+ 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);
+ 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;
+}
+
+
+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",
+};
+
+
const til_module_t * til_lookup_module(const char *name)
{
- static const til_module_t *builtins[] = {
- &_blank_module,
- };
+ static const til_module_t *builtins[] = {
+ &_blank_module,
+ &_ref_module,
+ };
static struct {
const til_module_t **modules;
size_t n_modules;
© All Rights Reserved