summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
2023-05-26til_settings: add some settings and desc path printersVito Caputo
These print to a stdio FILE*, which for now is harmless since setup_interactively() will be the only consumer (... for now). If one needed the path in a buffer, they could use open_memstream() and pass that FILE* to the printers. And since commit 40feb61 there's already a dependency on the function, but it's icky to dig deeper into that portability trap. Although it seemed like rototiller actually compiled on MacOS at Gene's house, so maybe open_memstream() isn't as problematic as it once was. Anywhow, this commit only adds the path printing helpers, nothing is using them yet.
2023-05-26til_settings: add til_setting_spec_t.as_labelVito Caputo
Currently settings instances get labels from three sources: 1. explicitly labeled by a root-level til_settings_new() call, like main.c::til_settings_new(NULL, "video", args->video); 2. implicitly labeled in a spec.as_nested_settings w/spec.key 3. positionally labeled in a spec.as_nested_settings w/o spec.key But when constructing setting/desc paths, using strictly these settings instance labels as the "directory name path component" equivalent, leaves something to be desired. Take this hypothetical module setting path for example: /module/layers/[0]/viscosity Strictly using settings instance labels as-is, the above is what you'd get for the drizzle::viscosity setting in something like: --module=compose,layers=drizzle Which is really awkward. What's really desired is more like: /module/compose/layers/[0]/drizzle/viscosity Now one way to achieve that is to just create more settings instances to hold these module names as labels and things would Just Work more or less. But that would be rather annoying and heavyweight, when what's _really_ wanted is a way to turn the first entry's value of a given setting instance into a sort of synthetic directory component in the path. So that's what this commit does. When a spec has .as_label specified, it's saying that path construction should treat this setting's value as if it were a label on a settings instance. But it's special cased to only apply to descs hanging off the first entry of a settings instance, as that's the only scenario we're making use of, and it avoids having to do crazy things like search all the entries for specs w/.as_label set. It feels a bit janky but it does achieve what's needed with little pain/churn.
2023-05-26til: more setup desc handling fixupsVito Caputo
7ff8ef94 switched things to always describe relevant settings, but left some loose ends. Obvious fixups for those
2023-05-26setup,til: assert(desc) if setup_func() wants more settingsVito Caputo
In this "all settings require descs" world, when setup_func forgets to return a res_desc for a setting it wants, we can end up in an infinite loop situation. It's better to abort immediately on the assert to catch such a program error.
2023-05-26modules/compose: desc the layer and texture module name settingsVito Caputo
Like modules/checkers required for fill_module, we need to do the same for for compose. It's a little more weird in compose since compose::layers is a nested settings full of unnamed nested settings. But compose::texture is analogous to checkers::fill_module.
2023-05-26modules/checkers: desc the fill_module's name settingVito Caputo
The bare-value value_as_nested_settings.entries[0] setting which serves as the name for module lookup is in a sort of no-mans land between checkers and the underlying fill_module's setup. So we have to do this little bit of rigamarole in checkers, being the entity wiring up the nested module. The fill_module's setup_func won't be doing anything to describe the name's setting as it's only interested in its own settings. There will likely be some helpers made later to streamline this process of composing module/settings hierarchies.
2023-05-26til_settings: drop settings->label from generated labelVito Caputo
Since these are ultimately intended for use in path construction, it's redundant to include the settings->label in the generated label. Instead what's really useful is just the subscript part: /module/compose/layers/layers[0]/drizzle/viscosity Becomes: /module/compose/layers/[0]/drizzle/viscosity which is far better. It may seem silly to have both the positional subscript *and* the module name, as in why not just have: /module/compose/layers/drizzle/viscosity But there's a need ot handle potential collisions like so: /module/compose/layers/[0]/drizzle/viscosity /module/compose/layers/[1]/stars /module/compose/layers/[2]/drizzle/viscosity So then maybe you think; ok, why have the module name? just use the positional subscript since that alone prevents the collisions. Result: /module/compose/layers/[0]/viscosity ... /module/compose/layers/[2]/viscosity Well, now we've lost useful context. The viscosity setting recurs on multiple modules, and we don't know just at a glance what we're working with anymore. Hence, why there's both. The module name in the path makes things substantially more self-explanatory. These paths will likely be what you're looking at as the labels of tracks in a multitrack sequencer like GNU Rocket. So this decision is likely affecting the UX at that level in the fullness of time.
2023-05-26setup: remove vestigial key-as-value printVito Caputo
Since 1a8abe80dabd this ceased to be the right thing to do, since there's no longer the whole bare-key setting with null value. It's now always a value, and the key that's optional.
2023-05-24til_settings: til_setting_t,til_settings_t get parent pointersVito Caputo
Preparatory for constructing unique paths from a given setting/settings instance by walking up the tree
2023-05-23modules/rtv: log_channels s/{yes,no}/{on,off}/Vito Caputo
Using on/off for boolean settings is the established convention in rototiller, rtv went rogue here. Just make it consistent Sometimes it feels like this should be more flexible and support 0/1 yes/no true/false on/off by just having "boolean" typed settings. But I think it may actually pay off long-term to be so opinionated here and making serialized settings heirarchies directly hashable/comparable without major normalization steps (nothing beyond say... case normalization).
2023-05-23libs/sig: mechanical rename sig_t->sig_sig_tVito Caputo
sig_t collides with some signals-related system header on macos. Just prefix it under the sig namespace.. leaving sig_ops alone for now, but maybe they'll become sig_sig_ops in the future too. Note nothing in master actually uses libs/sig currently, but I have an experimental branch with a dusty module using it.
2023-05-23util: add macos support for getting number of CPUsVito Caputo
Without this mac builds w/brew must be falling through the single CPU default linux failure code.
2023-05-23modules/checkers: add seed to randomized pattern,dynamicsVito Caputo
this oversight becomes apparent when stacking checkers as compose layers w/random pattern and/or dynamics. The stacked instances would identical pseudo-random behaviors for lack of seeding.
2023-05-23modules/checkers: fix transposed seed,ticks argumentsVito Caputo
These were being supplied backwards to til_module_context_new(), which mostly just meant the seed always started @ 0 for early checkers contexts, or were just slightly different ticks values for later ones.
2023-05-21modules/shapes: fixup clearing when {letter,pillar}boxedVito Caputo
3b6e34e70 broke this with what looks to be a silly mistake in modifying the existing put_pixel() calls. Kept the fragment->{x,y} instead of removing those and keeping the bare {x,y}.
2023-05-19modules/checkers: also set texture->frame_{width,height}Vito Caputo
These are expected to match, and it's asserted as such in various fragmenters. Especially now that we're getting more exuberant with recursive settings/modules, the correctness of the checkers cells fragment is becoming more exercised/important.
2023-05-19til_fb: clip get_pixel_clipped() to fragmentVito Caputo
til_fb_fragment_get_pixel_clipped() was clipping to the frame bounds, which are actually just a logical dimension for placing and scaling fragments within a frame. drizzle in particular is leaning on this clipped-get to prevent accessing outside of the fragment's backing buffer. Let's just clip it to the fragment bounds instead, see comment added for more information.
2023-05-17modules/rtv: make hermeticVito Caputo
As-is it's not great for rtv to randomly wind up in compositions, see comment in commit for more context.
2023-05-15til: fix til_setup_module() skip-experimental bugVito Caputo
Commit d72e924a introduced skipping experimental modules for the values, but it didn't bring in a new index for storing the values so the offset w/skips was being used to store the values too. This created a sparse set of values for the setup, manifesting as a wonky partial interactive setup for the module that didn't even include the default 0 (rtv) value in the list. Simple fix.
2023-05-11til_settings: free nested settingsVito Caputo
til_settings_free() needs to recur on nested settings
2023-05-11til_settings: rename til_settings_t.settings to entriesVito Caputo
settings->settings[] is obnoxious largely mechanical rename to settings->entries[]
2023-05-11modules/rtv: settings-ize snow_module=Vito Caputo
first step towards settings-izing rtv, channels[] remains
2023-05-11modules/compose: settings-ize layers and textureVito Caputo
Now layers= is a settings instance. Each individual setting within that layers instance is also a settings instance of its own. This enables specifying the modules used in the layers as well as settings to be passed into those per-layer modules. The escaping quickly becomes brutal if hand-constructing, but programmatically at least it's workable. Plus, you can let the interactive setup ask you for all the layer settings then just copy and paste the cli invocation printed @ startup (at least with rototiller). texture= is also now a settings instance, which means compose no longer randomizes the texture settings on its own - it instead uses the settings supplied. A consequence of this is that texture settings need to be actually populated if the texture is used. For rtv, which randomizes settings, it makes no difference and rtv compose invocations w/textures will just end up randomizing the texture through the normal setup randomizing machinery. But for direct compose invocations for instance, there's now an actual texture setup process - and if you just use --defaults, the defaults will be applied which is different from before where it would have always been randomized. This area needs some work, like controlling how defaults are applied perhaps in the actual settings syntax such that randomizing can still be performed if desired instead of "preferred" defaults. That's a more general settings syntax problem to investigate
2023-05-11modules/checkers: settings-ize fill_moduleVito Caputo
fill_module= now takes a settings string, so you can specify not just the name of the module, but additional settings passed into that module's setup. The fill_module's context path is also now getting fill_module appended, but see the large comment surrounding that mess WRT checker's per-cpu fill_module context creations.
2023-05-11modules/*: stop storing setup by value in contextsVito Caputo
With setup refcounting and a reference bound to the context, we should just dereference the single instance. The way setups are used it just as a read-only thing to affect context behavior... Note I've left the module-type-specific setup pointer despite it duplicating the setup pointer in the module_context. This is just a convenience thing so the accessors don't have to cast the general til_setup_t* to my_module_setup_t* everywhere.
2023-05-11til_module_context: reference setup from module contextVito Caputo
This just does the obvious pulling in of til_setup_t, holding the reference throughout the lifetime of the module context.
2023-05-11til_setup: refcount til_setup_tVito Caputo
The whole point of til_setup_t is to represent the baked, most conveniently usable form of a setup derived from one or more settings instances. Things generally go from the serialization format "settings string" to til_settings_t eventually culminating in a til_setup_t. So the process of making a til_setup_t is rather tedious and kind of costly. Once into a til_setup_t it's desirable to just hang on to this form and reuse it if possible. The way a til_setup_t baked setup is put to use is in a read-only fashion where it basically just informs behavior, so it makes a lot of sense to enable refcounting the thing and letting whatever can make use of it bump the refcount and hold onto the pointer, accessing the contents whenever it needs to answer a question about that particular setup. The immediate impetus for this is actually rtv's snow_module setup. In rtv every channel switch may recreate the context, if the context has expired. In the case of the snow module, the context always expires, and we definitely want to discard the context while playing the next channel. But when the snow resumes, in order to recreate the context as configured, we need the same setup again. It just becomes clear that what's needed is a way to pin the snow_module's setup for this reuse to be safe. There's also plenty of other modules that have been piecemeal copying settings into their context, when what would really make more sense is to just ref it and stow the pointer, then unref on their context destroy. They can just access the setup via the pointer as needed, instead of having to duplicate the setup in their context. Indeed, some module contexts even embed the entire setup just to copy its contents over by value. In simple/small scenarios that's fine, and I'm sure in those particular cases it's perfectly safe to do. It just seems unnecessary altogether. Another small change made is supporting NULL free_func, which will default to libc's free(). Most til_setup_new() call sites are passing free() with an annoying cast, those can be changed to NULL.
2023-05-11modules/*: remove use of static default setupsVito Caputo
There was a time when it made sense for context creates needing setups but not receiving them to still be functional with some sane defaults. But with recursive settings, we really shouldn't ever have orphaned nested module uses unreachable by a proper setup. So let's just get rid of this fallback, and exclusively rely on the baked setups provided by the .setup() methods. They still have preferred defaults, and the proper setup production machinery is what should be responsible for applying those at runtime where they may also be overridden or otherwise influenced.
2023-05-11til: add setup assert in til_module_create_context()Vito Caputo
If the module has a .setup() method, it should be able to just blindly expect a valid baked setup to come in @ context create. Let's enforce that here, and let the module code providing setup hooks just go forth and access the setup assuming it's at least present and as valid as their setup method produces.
2023-05-11modules/rtv: add basic log_channels= settingVito Caputo
This introduces a boolean style log_channels= setting for enabling logging of channel settings on channel switch. It might be nice to change this to accept stdout/stderr/fdnum as the setting instead of always directing at stderr. This also doesn't capture the seed state so it's not exactly logging everything needed to reproduce wholly what is being shown. Some compositions depend more on rand than others, so it matters at varying degrees. It'd be nice for settings syntax to have some global syntax supported where a seed can always be embedded to be loaded. Introducing such things as global settings to the settings syntax is a pending TODO item... right now the only way to load seed state is at startup passed to main as --seed=. That's not gonna cut it long-term. This is an easy big step in the right direction though. Trying to make sense of what's on-screen from the truncated captions is impossible. Even if the captions wrapped the settings, it would be tricky to catch the settings without recording the output or screenshotting. This also immediately makes me wonder about the voting system for rtv where we log settings of favorites... then roll those into playlists.
2023-05-11til: teach til_randomize_setup() about nested settingsVito Caputo
This probably needs more work, but it's good enough for now
2023-05-11setup: label anon nested settings as subscriptsVito Caputo
It'll be perfectly normal to turn bare-value settings int nested instances. In such scenarios we don't have a static spec-supplied key for the label, so let's just generate a label like a C-style array subscript for such instances.
2023-05-11til_settings: helper for labeling positional instancesVito Caputo
When there's a bare-value setting turned into a nested settings instance, there's no key onhand for labeling the instance. But such nameless settings are basically array elements only positionally accessed. This helper produces labels in that style for such settings by taking the container settings label and adding [$idx] to the end. These labels aren't really used as more than a debugging aid at the moment. But module contexts already have paths in main, and it seems like these settings instance labels will likely become the name components in constructing those paths.
2023-05-11til_settings: recursive til_settings_as_arg()Vito Caputo
Currently in rototiller the only (de)serialization format of settings is the args strings, so this is a rather critical piece to get in for recursive settings to really be usable. This is a quick and dirty implementation utilizing open_memstream() which despite being POSIX has spotty support (I don't think MacOS has it for instance). So that's probably something to rip out in the future. Nonetheless, this moves things forward and works fine on GNU.
2023-05-11til_settings: make use of til_setting_desc_t.containerVito Caputo
This commit pivots everything over to using desc->container as the target settings instance when adding settings, as well as actually assigning the settings container @ desc create. Given nothing is actually triggering settings heirarchies yet (no specs set as_nested_settings) this shouldn't actually result in any realized functional difference, yet. The settings pointer being placed in desc->container should be identical to what was getting used before.
2023-05-11til_settings: don't check values on nested settingsVito Caputo
There needs to be more flexibility in the value checking enforcement. This is just a quick blunt-hammer fix to not trip over nested settings values which will be huge undeterministic messes vs. what's likely just a set of simple presets in the spec.values[] The individual leaf settings will still be checked if they specify values. So this change just stops even bothering to check unless the setting is a leaf. This area needs more work in general, see comments. For instance right now we can't just pass in arbitrary floats for settings which list float values, not if that arbitrary float isn't a member of the list. In some circumstances that's the right thing to do, as in the module can only work with the presets. But most of the time, the module would be perfectly happy with e.g. foo=.3379 with foo's spec.values[] = { .01, .1, .25, .75, 1} so the check fails. That's dumb, and interferes with the creative process when you're just poking different numbers into the settings to see what happens. TODO
2023-05-11til_settings: add til_settings_get_count()Vito Caputo
Getter for accessing til_settings_t.num With recursive settings modules will start using settings instances to represent things like lists of module names. (modules/compose::layers for instance) For those cases they'll want to know the number of settings in the instance before iterating across getting their values positionally.
2023-05-11til_settings: introduce til_setting_spec_t concept vs. descVito Caputo
For recursive settings the individual setting being described needs to get added to a potentially different settings instance than the one being operated on at the top of the current setup_func phase. The settings instance being passed around for a setup_func to operate on is constified, mainly to try ensure modules don't start directly mucking with the settings. They're supposed to just describe what they want next and iterate back and forth, with the front-end creating the settings from the returned descs however is appropriate, eventually building up the settings to completion. But since it's the setup_func that decides which settings instance is appropriate for containing the setting.. at some point it must associate a settings instance with the desc it's producing, one that is going to be necessarily written to. So here I'm just turning the existing til_setting_desc_t to a "spec", unchanged. And introducing a new til_setting_desc_t embedding the spec, accompanied by a non-const til_settings_t* "container". Now what setup_funcs use to express settings are a spec, otherwise identically to before. Instead of cloning a desc to allocate it for returning to the front-end, the desc is created from a spec with the target settings instance passed in. This turns the desc step where we take a constified settings instance and cast it into a non-const a more formal act of going from spec->desc, binding the spec to a specific settings instance. It will also serve to isolate that hacky cast to a til_settings function, and all the accessors of til_setting_desc_t needing to operate on the containing settings instance can just do so. As of this commit, the container pointer is just sitting in the desc_t but isn't being made use of or even assigned yet. This is just to minimize the amount of churn happening in this otherwise mostly mechanical and sprawling commit. There's also been some small changes surrounding the desc generators and plumbing of the settings instance where there previously wasn't any. It's unclear to me if desc generators will stay desc generators or turn into spec generators. For now those are mostly just used by the drm_fb stuff anyways, modules haven't made use of them, so they can stay a little crufty harmlessly for now.
2023-05-11til_settings: rework setting get/add for bare valuesVito Caputo
The core thing here is rather than turning a bare value into a key as I was doing before - we just leave the bare value as a bare value and its setting must be located positionally via get_value_by_idx since there's no key. Existing callers that used to get_key() positionally now get_value_by_idx() positionally all the same, except it's the value instead of the key. This is mostly done for things like the module or fb name at the front of a settings instance. The impetus for this change is partially just cosmetic/ergonomics, but it's also rather strange for what's really a key-less value to be treated as a value-less key. It was also awkward to talk/reason about on the road to recursive settings where bare values would be supported as a standalone settings instance if properly escaped... This also adds unescaping of keys, and adds a dependency on the somewhat linux-specific open_memstream() which may need changing in the future (see comments).
2023-05-11setup: constify settings passed to setup_funcVito Caputo
setup_func isn't formally defined for libtil, but setup_interactively() defacto establishes it and til_module_t.setup() reflects the same signature and calling convention except with til_settings_t constified. This change makes them all consistent in this regard, but there should probably be a formal typedef added for the function. The reason for constifying this is I don't want setup functions directly manipulating the settings instance. In the case of rototiller::setup_interactively() we ensure the stdio-based interactive setup is always the side doing the manipulation of the settings. For a libtil-user like glimmer, it's slightly different beast with GTK+ in the loop, but by preventing the setup_funcs from messing directly with the settings (instead having to describe what they want done iteratively), the front-end always gets its opportunity to maintain its state while doing the described things. Of course, this is mostly a lie, and within libtil the constified til_settings_t gets cast away to modify it in places. But keeping that limited to within libtil is tolerable IMO. We just don't want to see such casts in module code.
2023-05-11main: quote shown flags/argsVito Caputo
Preparatory commit for recursive settings going cray-cray with escaping. At least single-quote these so it's directly copy-and-pasteable into a shell prompt.
2023-05-11til_settings: add til_setting_desc_t.as_nested_settingsVito Caputo
When this is set, the setting is itself to be a settings instance that the frontend must create and place in the relevant til_setting_t.value_as_nested_settings. This commit implements that frontend portion in setup_interactively() for the rototiller frontend. No setup_func() yet attempts to make use of this stuff. There's probably more change needed before that can happen, specifically the setup_func() likely must always produce a til_settings_t* to indicate which settings instance is currently relevant to the frontend. Without setup_func() telling the frontend, the frontend has basically no other way of knowing when the backend setup_func() has moved up/down the heirarchy at the current iteration.
2023-05-11til_settings: add til_settings_t.value_as_nested_settingsVito Caputo
Preparatory commit for settings hierarchies.
2023-05-10til_settings: label til_settings_t instancesVito Caputo
This adds a mandatory label string to til_setttings_new() and updates call sites accordingly. For now the root-level settings created by main.c are simply named "module" and "video" respectively. Any nested settings creations on behalf of modules will be labeled using the module's name the settings are being created for use with. This might evolve with time, for now it's just a minimum churn kind of decision. I can see it changing such that the top-level settings also become labeled by the module/video driver name rather than the obtuse "module" "video" strings. How these will be leveraged is unclear presently. At the least it'll be nice to have a label for debugging til_settings_t heirarchies once recursive settings support lands. In a sense this is a preparatory commit for that work. But I could see the labels ending up in serialization contents as markup/syntactic sugar just to self-document things as well. There might also be a need to address til_settings_t instances in the settings heirarchy, which may be something like a "label/label/label/label" path style thing - though there'd be a need to deal with name collisions in that approach. I'm just thinking a bit about how knobs will become addressed when those become a real thing. The settings label heirarchy might be the convenient place to name everything in a tree, which knobs could then inherit their parent paths from under which their respective knob labels will reside. For the whole name collision issue there could just be some builtin settings keys for overriding the automatic module name labeling, something like: --module=compose,layers=checkers\,label=first\,fill_module=shapes:checkers\,label=second\,fill_module=shapes would result in: /module/first/shapes /module/second/shapes or in a world where the root settings weren't just named "module" and "video": /compose/first/shapes /compose/second/shapes then if there were knobs under checkers and shapes, say checkers had a "foo" knob and checkers had a "bar" knob, they'd be under .knobs in each directory: /compose/first/.knobs/foo /compose/first/shapes/.knobs/bar /compose/second/.knobs/foo /compose/second/shapes/.knobs/bar something along those lines, and of course if compose had knobs they'd be under /compose/.knobs This is just a brain dump and will surely all change before implemented.
2023-05-09modules/compose: pass n_cpus to layers/texture context createsVito Caputo
Existing code was passing 0 which turns into the number of cores/threads. That's fine when compose isn't running nested in an already threaded render, but falls down in something like checkers w/fill_module=compose since checkers is already threading. But when checkers creates its fill_module context, it's careful to pass 1 for n_cpus to prevent that kind of thing. With this change that no longer falls apart.
2023-03-13modules/rocket: mv modules/rocket modules/rktVito Caputo
Finishes build/fs part of modules/rocket->modules/rkt rename started in previous commit.
2023-03-13modules/rocket: %s/rocket/rkt/gVito Caputo
It's annoying to have the til module called rocket, and the sync tracker protocol/library called rocket, so let's at least differentiate it in code/comments/textual discussion. Plus this results in shorter module context paths i.e.: /rkt:scene /rkt/compose/drizzle:rain /rkt/compose/drizzle:viscosity /rkt/compose/plato:spin_rate /rkt/compose/plato:orbit_rate vs. /rocket:scene etc... These names are shown in the editor, and they'll tend to be long but let's at least get the root name down to three chars this way. A rename of the files and build system update will come in a subsequent commit
2023-02-23libs/rocket: bump submodule and enable TCP_NODELAYVito Caputo
Upstream merged my TCP_NODELAY PR, so let's get it in rototiller. Note I'm blindly setting USE_NODELAY now, but it might actually break the build for win32 - still need to test that.
2023-02-06til: get rid of the partial knobs implementationVito Caputo
With taps more or less fully implemented, it seems appropriate to get rid of the stubbed out knobs for now. Taps don't express the same things about range and usage knobs aspired towards, but they don't preclude adding such things either. But it seems clear that the way knobs were stubbed won't be complementing taps as things stand currently to add those aspects.
2023-02-06modules/meta2d: add some taps for controlling visible bandVito Caputo
There should probably be others for the ball radiuses, and colors
© All Rights Reserved