diff options
| -rw-r--r-- | src/til.c | 136 | 
1 files changed, 133 insertions, 3 deletions
| @@ -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; | 
