summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2023-05-27modules/voronoi: threaded calculate_distances()Vito Caputo
This seems to work on my 2c/4t laptop and is certainly faster. But I'm not being careful about using atomics loading/storing the d->cell pointer, which seems problematic. Surprisingly things aren't crashing here despite that, maybe on a non-x86 smp box it'd be a different story.
2023-05-27modules/voronoi: split voronoi_calculate_distances()Vito Caputo
Preparatory commit for doing the voronoi distance calculations in parallel when possible, as part of render_fragment() instead of all in prepare_frame(). Not all of the distance calculation work can easily be threaded, but it should be possible to compute the post-seed distances concurrently within the spatial bounds of the tiled fragment. This commit doesn't actually change anything functionally, as it's just splitting the old voronoi_calculate_distances() into two and calling them both in succession still from voronoi_prepare_frame(). Subsequent commits will work towards making the render_pass() fragment-aware then ultimately moved to voronoi_render_fragment()
2023-05-27modules/voronoi: remove dirty= setting and variantVito Caputo
This variant is kind of a broken hack, and its brokenness becomes more apparent in a threaded voronoi world. So just drop it for now. I am interested in more voronoi variants, but they can't compromise correctness/introduce instabilities or significantly interfere with performance improvements like threaded rendering. The dithered-ish look of dirty=on was an interesting variant though... bummer.
2023-05-27modules/voronoi: constify til_fb_fragment_tVito Caputo
trivial change; voronoi_sample_colors() only reads from the fragment
2023-05-27modules/rtv: desc the snow_module name settingVito Caputo
Like modules/checkers required for fill_module, we need to do the same for for rtv::snow_module. There's more work to do on rtv::channels, but that's still unsettled stuff in terms of settings syntax since rtv randomizes settings. It's desirable to have the rtv settings able to specify which settings to hold constant at a specific value per-channel, leaving everything else for randomizing on channel switch. But there's no syntax for that kind of stuff currently, and it seems like there's a need to communicate during the setup_func dance when we're in a "settings optional because we'll fill them in automatically at time of use later" to the front-end. It's not strictly a front-end issue though - because the back-end setup_func actually controls the forward progress. From the current setup_func's perspective, everything's important to it and must be fulfilled. And we certainly want the setup_func to continue informing the setup process. So it's more like the channel settings being populated via rtv still need to all get populated, rtv just needs a way to add an attribute to mark which settings are static vs. which should get randomized on every use. Perhaps there should just be a special value syntax reserved for saying "random value" and the front-end can apply that, but then a til_module_randomize_setup() could detect that too in a per-setting flag the front-end set. That way the value gets re-randomized, while the ones without that value set get left alone. Yes, I know this isn't the appropriate place for such commentary. But nobody is reading these things anyways on my toy side project.
2023-05-27modules/compose: trivial indentation fixupVito Caputo
2023-05-27modules/rtv: don't use n_cpus=0 for the context createsVito Caputo
This is harmless as long as rtv stays hermetic. But if rtv gets used in a composite scenario in the future by either removing the hermetic flag, or allowing forced overrides, n_cpus=0 will cause the nested module contexts to become threaded on SMP machines. That's problematic if the outer module context is already a threaded render. What's appropriate here is to just propagate the n_cpus down so if an upper layer has already gone threaded, it will be sending down n_cpus=1 to serialize the nested instances. In practice, as-is, this change basically changes nothing, but prepares for a potential future where rtv participates in threaded compositions. Through a lens of "rtv just rejiggers scenes and there settings on a timer from a settings-specified subset of modules and settings" it's arguably useful as just another module. Sometimes you want something to change itself up periodically in say a compose layer. So preparing for this possibility isn't really all that far-fetched/hypothetical.
2023-05-26setup: print paths to the settings being setupVito Caputo
This commit introduces setting path printing to interactive setup, making it much more clear what on earth you're setting up in more complex scenarios. e.g. an interactive setup of module=compose is now: ``` $ src/rototiller --module=compose /module/compose/layers: Comma-separated list of module layers, in draw-order [drizzle,stars,spiro,plato]: /module/compose/layers/[0]/drizzle/viscosity: Puddle viscosity: 0: .005 1: .01 2: .03 3: .05 Enter a value 0-3 [1 (.01)]: /module/compose/layers/[0]/drizzle/style: Overlay style: 0: mask 1: map Enter a value 0-1 [0 (mask)]: /module/compose/layers/[1]/stars/rot_adj: Rotation rate: 0: .0 1: .00001 2: .00003 3: .0001 4: .0003 5: .001 Enter a value 0-5 [2 (.00003)]: /module/compose/layers/[3]/plato/orbit_rate: Orbit rate and direction: 0: -1 1: -.75 2: -.5 3: -.25 4: .1 5: 0 6: .1 7: .25 8: .5 9: .75 10: 1 Enter a value 0-10 [7 (.25)]: /module/compose/layers/[3]/plato/spin_rate: Spin rate and direction: 0: -1 1: -.75 2: -.5 3: -.25 4: .1 5: 0 6: .1 7: .25 8: .5 9: .75 10: 1 Enter a value 0-10 [9 (.75)]: /module/compose/texture: Module to use for source texture, "none" to disable: 0: none 1: blinds 2: checkers 3: drizzle 4: julia 5: moire 6: plasma 7: roto 8: stars 9: submit 10: swab 11: voronoi Enter a value 0-11 [0 (none)]: 1 /module/compose/texture/blinds/orientation: Blinds orientation: 0: horizontal 1: vertical Enter a value 0-1 [0 (horizontal)]: /module/compose/texture/blinds/count: Blinds count: 0: 2 1: 4 2: 8 3: 12 4: 16 5: 24 6: 32 Enter a value 0-6 [4 (16)]: 3 /video: Video backend: 0: drm 1: mem 2: sdl Enter a value 0-2 [2 (sdl)]: /video/sdl/fullscreen: SDL fullscreen mode: 0: off 1: on Enter a value 0-1 [0 (off)]: /video/sdl/size: SDL window size [640x480]: Configured settings as flags: --seed=0x6471f827 '--module=compose,layers=drizzle\\\,viscosity\\\=.01\\\,style\\\=mask\,stars\\\,rot_adj\\\=.00003\,spiro\,plato\\\,orbit_rate\\\=.25\\\,spin_rate\\\=.75,texture=blinds\,orientation\=horizontal\,count\=12' '--video=sdl,fullscreen=off,size=640x480' Press enter to continue, add --go to skip this step... ``` Previously it would be like so: $ src/rototiller --module=compose Comma-separated list of module layers, in draw-order [drizzle,stars,spiro,plato]: Puddle viscosity: 0: .005 1: .01 2: .03 3: .05 Enter a value 0-3 [1 (.01)]: Overlay style: 0: mask 1: map Enter a value 0-1 [0 (mask)]: Rotation rate: 0: .0 1: .00001 2: .00003 3: .0001 4: .0003 5: .001 Enter a value 0-5 [2 (.00003)]: Orbit rate and direction: 0: -1 1: -.75 2: -.5 3: -.25 4: .1 5: 0 6: .1 7: .25 8: .5 9: .75 10: 1 Enter a value 0-10 [7 (.25)]: Spin rate and direction: 0: -1 1: -.75 2: -.5 3: -.25 4: .1 5: 0 6: .1 7: .25 8: .5 9: .75 10: 1 Enter a value 0-10 [9 (.75)]: Module to use for source texture, "none" to disable: 0: none 1: blinds 2: checkers 3: drizzle 4: julia 5: moire 6: plasma 7: roto 8: stars 9: submit 10: swab 11: voronoi Enter a value 0-11 [0 (none)]: 1 Blinds orientation: 0: horizontal 1: vertical Enter a value 0-1 [0 (horizontal)]: Blinds count: 0: 2 1: 4 2: 8 3: 12 4: 16 5: 24 6: 32 Enter a value 0-6 [4 (16)]: 3 Video backend: 0: drm 1: mem 2: sdl Enter a value 0-2 [2 (sdl)]: SDL fullscreen mode: 0: off 1: on Enter a value 0-1 [0 (off)]: SDL window size [640x480]: Configured settings as flags: --seed=0x6471f827 '--module=compose,layers=drizzle\\\,viscosity\\\=.01\\\,style\\\=mask\,stars\\\,rot_adj\\\=.00003\,spiro\,plato\\\,orbit_rate\\\=.25\\\,spin_rate\\\=.75,texture=blinds\,orientation\=horizontal\,count\=12' '--video=sdl,fullscreen=off,size=640x480' Press enter to continue, add --go to skip this step... ``` Which gets rather confusing, especially if you go even deeper with nested module situations like compose/layers/[0]/checkers/fill_module/compose/layers/[0]/drizzle You just lose track of which module instance's settings you're actually setting up This is just the first step of making use of these paths. In the future the module context paths will be derived from the settings paths so they're more reliably distinct and descriptive, along with consistent with paths in the settings namespace. That becomes important when module contexts start getting registered on the stream for use in other modules.
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.
© All Rights Reserved