Age | Commit message (Collapse) | Author |
|
When a driving tap becomes inactive, til_stream_tap() should be
able to notice and replace the driver.
An example driving tap becoming inactive would be a GNU Rocket
track that once had keys in it, but then had them all deleted.
This should set the inactive flag so the tap's automation can
take over. This gives the user at the Rocket editor the ability
to both take over from the tap automation and surrender control
back, by populating vs. emptying the respective track.
|
|
We need a way to identify owners of taps when cleaning up
their containing contexts, especially once they're hanging off
streams.
|
|
Just some banal paperwork...
|
|
The purpose of the tap is ultimately to be indexed by name so
it's discoverable. I'm leaning towards using a hash table for
that, and it'd be silly to keep recomputing the hash of an
unchanging name.
|
|
this is slightly more ergonomic by having one less pointer to get in
the right place in the parameters
|
|
The previous commit implemented taps in a way requiring
allocations and cleanup. Let's experiment a bit and just make
them absolutely minimal named typed variable+indirection
bindings.
The helpers are retained, but converted to initializers rather
than new() style constructors. They provide type-checking of the
variable and indirection pointer, and prevent incorrect TIL_TYPE
values going in til_type_t.type for the supplied bound
elems+ptr.
|
|
The idea here is for modules to bind variables to names @ context
create time w/til_tap_new(). Pseudo-code sample:
```
typedef struct foo_context_t {
struct {
til_tap_t *position;
} taps;
struct {
v2f_t position;
} vars;
v2f_t *position;
} foo_context_t;
foo_context_t * foo_create_context(void)
{
foo_context_t *foo = malloc(sizeof(foo_context_t));
/* This creates an isolated (pipe-)tap binding our local position variable and pointer
* to a name for later "tapping" onto a stream.
*/
foo->taps.position = til_tap_new_v2f(&foo->position, "position", 1, &foo->vars.position);
return foo;
}
foo_render(foo_context_t *foo, til_fb_fragment_t *fragment)
{
if (!til_stream_tap(fragment->stream, &foo->pipes.position)) {
/* got nothing, we're driving */
foo->position->x = cosf(ticks);
foo->position->y = sinf(ticks);
} /* else { got something, just use foo->position as-is */
draw_stuff_using_position(foo->position);
}
```
Note til_stream_tap() doesn't exist yet, this commit only adds
the tap (til_tap_new()).
The stream will probably implement a hash table for looking up
the tap by name, verifying its type and nelems match if found,
and update the pointer to point at the instance actually driving
for the name. (in the example that's the foo_context_t.position
pointer which draw_stuff_using_position() then dereferences)
Also note that in the example, "position" alone is too simplistic
for handling complex real-life compositions where a given module
may recur in a given stream. That identifier would need to be
derived from the module's context/setup producing a distinctly
unique path to the tap. i.e.
"/compose/layers/checkers/fill_module/foo:position" or something,
to be dynamically generated. And the foo:position syntax isn't
set in stone either. Maybe foo/position would suffice, the whole
heirarchical syntax needs to be thought through and defined yet.
Since the absolute path to the tap would be setup-dependent, there
will have to be some glue tying together the setup used by the
context and the tap within that context. The stream may be the
natural place where that occurs.
This also currently is barebones in terms of the tap types
supported. The only higher-order types are rudimentary 2-4d
vectors and 4x4 matrices. There are no semantics associated
with the types, and it's likely in the future either the tap
types themselves will expand to be semantic. Think things like
a camera type, composed both a point and direction vector.
As-is the few higher-order types in til_tap.h are simply forward
declared, and at least in terms of the taps alone further type
visibility isn't necessary.
It may make more sense to build upon these bare taps with another
semantic layer bringing the higher-order types to the table in a
more concrete form. All those higher-order types would then be
composed from the bare taps.
There's some conceptual overlap with the knobs stubbed out in
til_knobs.h as well. I think this likely at least partially
replaces what's there, and what it doesn't will probably end up
somewhere else.
|