summaryrefslogtreecommitdiff
path: root/src/til.c
AgeCommit message (Collapse)Author
2023-07-31modules/signals: experimental signals moduleVito Caputo
Playing with libs/sig in 2D, this isn't really an interesting module by itself in terms of visual output. But it might have utility as a diagnostic thing if libs/sig becomes a more used thing. At the very least, for now, it's useful for observing affects of and iterating on libs/sig development. So I'm merging this, just gated behind TIL_MODULE_EXPERIMENTAL so it's not in rtv rotation or presented as something in the usual modules list.
2023-07-28til: add til_fragmenter_slice_per_cpu_x16() variantVito Caputo
This restores the original til_fragmenter_slice_per_cpu() while adding an explicit x16 variant for what til_fragmenter_slice_per_cpu() had become. The impetus for this is realizing the x16 multiplier is terrible for sparkler's crappy threading, and it really need strictly n_cpus slices for the threading to be beneficial. So I'm just getting rid of the hidden x16 in favor of making it explicit in an _x16 variant. Subsequent commit will pivot all the non-sparkler callers to til_fragmenter_slice_per_cpu_x16().
2023-07-28til: use til_module_render_limited() in "ref" builtinVito Caputo
Since "ref" renders using arbitrary foreign contexts, it must explicitly limit their rendering concurrency to its own.
2023-07-28til: introduce til_module_render_limited() variantVito Caputo
With the introduction of discoverable on-stream contexts, with the intention of modules finding them at runtime for nested rendering, relying exclusively on limiting n_cpus @ til_module_create_context() is no longer adequate. When the nested rendering makes use of a context created elsewhere, it can't make any assumptions about what its n_cpus is, nor should it be attempting to change that value for its use. So this variant just adds a max_cpus parameter for setting an upper bound to whatever is found in the context's n_cpus. The impetus for this is to fix the ref builtin, which you can currently trick into deadlock by performing a nested threaded render within a threaded render. What the ref module should be doing is propagating its own context's n_cpus down as the upper bound, via this new render variant.
2023-07-10til: introduce "noop" builtinVito Caputo
When profiling compositions it's convenient to suppress some modules in the settings to see how their omission affects the FPS. There's already a "blank" builtin which clears the fragment, but there's no way to turn the cost to ~zero. This "noop" builtin does just that, absolutely nothing - it won't even trigger the implicit "til_fb_fragment_t.cleared = 1" update so whatever rendering follows will still find an uncleared fragment if that's what came into the noop.
2023-07-09til: introduce til_module_setup_full()Vito Caputo
This moves the core til_module_setup() functionality out into a more composable helper with an eye towards all meta-modules using it for doing their module setup instead of all the ad-hoc stuff occurring presently. Since til_module_setup_full() needs more paramaters to influence its behavior, it's not directly usable as a "setup_func". But is trivially wrapped into one, which is what til_module_setup() has now become. It's in the wrapper that users are expected to do specify what's necessary for influencing til_module_setup_full() to do what's appropriate for their needs.
2023-07-08til: add timersub macro for __WIN32__Vito Caputo
just quick and nasty hacking to make win32 build again
2023-07-08til: measure til_module_render() durationsVito Caputo
This stows the duration (in ticks (which are ms for now)) of a given module context's most recent, as well as tracking the max, in til_module_context_t. For now it's also added to --print-module-contexts output, but this is still rather primitive and nearly inscrutible in practice... that output is a flickery and unsorted mess during playback. But this is just a start. Ticks may need to move up to microseconds if it'll also be the units for measuring timings. Right now things are slow enough that the low-hanging fruit stand out as multiple if not dozens of milliseconds so it's still useful for now.
2023-07-07til: introduce til_ticks_now()Vito Caputo
Thin wrapper around gettimeofday(), prolly change the main ticks stuff over to this too.
2023-07-05til: more strictly filter til_module_setup()Vito Caputo
It was too coarse a condition filtering the list on !name. This change actually looks up non-NULL names to verify it's a resolvable module name before producing the unfiltered list. Mostly just to prevent fat-fingered manual module inputs from resulting in unexpectedly larger and potentially dangerous module lists in interactive "invalid input" retries. Observed in the WIP rkt_scener stuff...
2023-07-05til: describe module name in til_module_setup_randomize()Vito Caputo
It just happened to be tolerable that the first setting in these randomized settings instances wasn't ever getting described... due to the ad-hoc nature of how rtv used them. But in preparation for rkt_scener which will have "randomize scene" functionality, as well as interactive (re)configuring of the scenes, these settings instances need to be more correct to not break things. It seems awkward to be duplicating this "Renderer module" desc here however. But I just want to make progress on the scene editor for rkt, I suspect this will be revisited in the future. On a high-level it feels like til_module_setup() should be the thing producing that desc, and the randomizer just picking the random settings through that setup func.
2023-07-04til: make til_modlue_setup() nested usage awareVito Caputo
When setting up a nested module, the HERMETIC modules shouldn't be considered as eligible nor should one be the preffered option (rtv). This uses the presence of a parent on the settings as a heuristic for if it's a nested scenario (no parent == root). When nested the default changes to "compose" from "rtv", and HERMETIC modules are omitted from the listed values.
2023-07-04til: optionally finalize in til_module_setup()Vito Caputo
This was assuming non-NULL res_setup which would assert in til_module_setup_finalize() which doesn't expect a NULL res_setup since that's its entire purpose. It's not a bug that was actually triggered by any callers (yet)
2023-06-19til: use 16 * n_cpus in til_fragmenter_slice_per_cpu()Vito Caputo
Slight improvement of CPU utilization for fragmenters using this strategy... I noticed tile64 would give better FPS in some scenarios where it seemed obvious slice_per_cpu() was the appropriate option. And that turned out to just be by virtue of being able to give idle threads something to do while busy ones finished what was on their plate. So just make the slices a bit more granular than n_cpus... this may have to be revisited in the future to find the sweet spot, and may need to be more sophisticated than just multiplying by a constant factor.
2023-06-15til_module_context: s/ticks/last_ticks/ in contextVito Caputo
And just maintain it as the last ticks value after rendering with the context... A couple modules were already doing this manually in an ad-hoc fashion, just make it a general thing. Updated those modules to reflect the new situation Especially in a rkt world with modules::mixer doing fades, it becomes common to render the same context twice in the same frame for the blending. We need to prevent accelerated animations in such situations. For now let's just rely on ticks in a delta-T fashion to prevent animating the context when ticks is the same. modules::stars in particular needs this fixed up, upcoming commit
2023-06-13til: til_module_setup() needs to finalize when no .setup()Vito Caputo
Commit 24911280 made til_setup_t required, and most setup code has already adopted til_module_setup_finalize() added in c94e4683 for this purpose. But til_module_setup()'s fall-through case when there's no til_module_t.setup() on the module being setup was missed. This broke running simple modules without a .setup() directly like --module=roto, oops. Fix is simple.
2023-06-13*: smattering of random small fixes to silence -WallVito Caputo
I thought the build was already using -Wall but that seems to not be the case, maybe got lost somewhere along the line or messed up in configure.ac After forcing a build with -Wall -Werror, these showed up. Fixed up in the obvious way, nothing too scary.
2023-06-12til: register contexts on-stream @ create timeVito Caputo
Module contexts are now discoverable via the stream a la til_stream_find_module_contexts(). The current architecture has the stream adding a reference to all the contexts registered. So even if they get unreferenced by their creators, they will linger on-stream. There's a gc mechanism til_stream_gc_module_contexts() which can be used to trigger a cleanup of contexts _only_ referenced by the stream. It's unclear as of yet if this is the way to go long-term, but it lets things work for now and allows some iterating and experimentation to see where to go next.
2023-06-12til: introduce "ref" built-in moduleVito Caputo
This opens up the possibility of referencing contexts on-stream by-path anywhere a module may be used: ref,path=/path/to/existing/context Currently the path lookup is performed @ render time, and a reference is taken on the context found there on the first time it's located. That reference is then held in the ref's context until its context is destroyed. There are more details to flesh out, and what probably needs to happen is some til_stream API for maintaining the reference in the event that the context at that path gets replaced. Due to refcounting, the referenced context will persist even if the stream-resident instance goes away, but there should probably be a way for that replacement to invalidate the existing references so they replace theirs with a fresh lookup at the path... Either way this is a good start. With this addition you can effectively implement scene transitions in rkt, via the mixer module, something like (sans proper escaping): mixer,a_module=ref\,path=/foo/previous/ctxt,b_module=ref\,path=/foo/next/ctxt
2023-06-11til: drop open_memstream() in til_get_module_names()Vito Caputo
open_memstream() isn't implemented by windows (not even mingw)
2023-06-11modules/mixer: add rudimentary mixer meta moduleVito Caputo
this is very early/unfinished, hence experimental flag
2023-06-05til: introduce til_module_create_contexts() variantVito Caputo
checkers::fill_module is presently implemented via creating n_cpus identical module contexts, each having n_cpus=1. Establishing a set of cloned per-cpu contexts, allowing threaded rendering using any fill_module, regardless of if that module internally implements threaded rendering. This works fine, but creates some awkwardness for a future where contexts are registered and discoverable within the stream at their respective setup's path. In the checkers::fill_module case, there would be n_cpus contexts at the same path since they share the same til_setup_t. Those need to be dealt with gracefully, ideally making the clones available to another potentially clone-needing module (imagine a checkers::fill_module transitionining to another checkers::fill_module situation, where the transitioned-to fill_module refers to the context by path, it should get all the contexts out of the stream as-is) In this commit I'm adding a more formalized method of creating multiple contexts from the same set of parameters, in preparation for a future where module contexts get registered on the stream at their til_setup_t.path. By putting the cloned creates behind the til API it should at least be relatively trivial to get the on-stream context registration to capture the multiple contexts.
2023-06-03til,modules/rtv: supply settings to til_module_setup_randomize()Vito Caputo
Rather than creating an orphaned settings instance private to til_module_setup_randomize(), the function now requires the settings instance be provided. The one remaining caller of this function is modules::rtv. Now that rtv is responsible for creating the settings beforehand, and the settings may be created with a path prefix, rtv gets its til_module_context_t->setup.path prefixed for all the channel settings. Another improvement is now the channel settings instance gets created from the module name as the settings string. So while it's not yet possible to sparsely specify settings with others being randomized, at least now when log_channels=on is in effect, the printed args include the top-level channel module. Having proper complete paths for the rtv channel modules is especially visible in --print-paths output FYI. An interesting test for exercising all this is: ``` $ src/rototiller --module=rtv,duration=0,context_duration=0,snow_module=none,channels=all,log_channels=on --print-pipes --defaults --go 2>/tmp/channels in another terminal: $ tail -F /tmp/channels ``` watch the chaos unfold
2023-06-03til: fix spurious empty res_arg in til_module_setup_randomize()Vito Caputo
r variable is checked for zero(success) before writing to *res_arg, but could be left uninitialized (especially in a future scenario where an incoming til_settings_t is fully populated and described).
2023-06-03til_settings: add an optional til_settings_t.prefixVito Caputo
Preparatory commit for bridging the gap separating a baked til_setup_t from a runtime-populated descendant til_settings_t like modules::rtv produces for its channels via til_module_setup_randomize(). For these currently orphaned til_settings_t instances we don't readily have access to the logical ancestor til_settings_t that was used to produce the module_context's bound til_setup_t. But we don't really need the ancestor til_settings_t, all we _really_ want is the ancestral path to prefix the orphan til_settings_t instances. So this commit introduces supplying a prefix which gets prepended to paths printed via the settings instance. A later commit will make use of this in modules::rtv when producing the settings instance passed to til_module_setup_randomize()
2023-06-03til: skip described settings in til_module_setup_randomize()Vito Caputo
Preparatory commit for when settings are supplied by caller, potentially populated and described.
2023-06-03til_settings: drop desc from til_settings_add_value()Vito Caputo
In a world where "describing" settings is an iterative process, especially post-nested-settings which are realized via the desc-applying process, it's better to not even offer desc-setting while adding a new setting. This commit just gets rid of that. The one caller that was passing a non-NULL desc to til_settings_add_value(), til_module_setup_randomize(), was redundantly doing so since the subsequent desc-processing was assigning it again anyways. Future commits will likely change til_module_setup_randomize() use a non-NULL desc for skipping desc-applying, which wouldn't even work if it was always setting the desc @ add time. That becomes necessary for partially randomizing sparsely-populated settings.
2023-06-03til: add exclusions to til_get_module_names()Vito Caputo
There's often a need to exclude specific modules, though it's often a hacky kludge. It's something relied upon currently for preventing dangerous recursion scenarios, which will likely get fixed up more robustly in the future.
2023-06-03til_settings,setup: introduce til_setting_spec_t.override()Vito Caputo
In situations where modules wish to alias setting values like expanding "all" -> "mod0,mod1,mod2,mod3" they need a way to intercept the value-acceptance @ desc-assignment time in the front-end. This optional override() function does just that when present in the spec. The current setting's value is passed to the override, and if what's returned differs from what was passed (by pointer value), then the current value is freed and the override takes its place. The override function is expected to _always_ return non-NULL; either the value provided, or a newly allocated value override. The override function must never free the supplied value, that's the front-end's job in applying the override. The override() must return NULL on errors, which are assumed to be limited to ENOMEM failures.
2023-06-03til: add til_get_module_names() helperVito Caputo
Composite modules that want to provide "all" aliases for modules like rtv have to construct a comma-separated string of all module names, usually filtered by some flags. This helper does just that, but it does add yet another open_memstream() user to revisit when those all get fixed up.
2023-05-30til: s/til_module_randomize_setup/til_module_setup_randomize/Vito Caputo
Mechanical rename just to make this consistent with til_module_setup()/til_module_setup_finalize() I should probably do a cleanup pass throughout the til APIs to standardize on a subject-verb-object or subject-object-verb order... Things have become a little inconsistent organically over time
2023-05-30til,*: pivot to til_setup_t for context pathsVito Caputo
This changes til_setup_t* from optional to required for til_module_context_t creation, while dropping the separate path parameter construction and passing throughout.
2023-05-30til: make til_module_randomize_setup() always produce a setupVito Caputo
Preparatory for required til_setup_t @ til_module_create_context() This basically brings til_module_randomize_setup() inline with til_module_setup_finalize() in that it will still produce a minimal til_setup_t even if there is no til_module_t.setup() method. A future commit will do something about the orphaned til_settings_t within til_module_randomize_setup() to get a full path on the produced setup - which will likely simultaneously bring us into a world where one can influence the randomized settings externally as well. Influenced in the sense of potentialy making some of those settings statically configured while leaving others to be (re)randomized at the time of til_module_randomize_setup() executing.
2023-05-30til: add til_module_setup_finalize() helperVito Caputo
Preparatory commit for til_module_create_context() requiring setups even when there's no til_module_t.setup() method. This helper will produce the minimal til_setup_t in such cases, or hand off the task to til_module_t.setup() when present. Note the need for passing res_setting and res_desc to til_module_t.setup() despite not being a settings-construction scenario. This is because of how modules using nested settings tend to use res_setting for storing the current setting in accessing the nested instance, which must still occur even when just baking the complete setup. It's expected that any composite/meta modules utilizing other modules will use this helper to produce the baked setups, instead of the ad-hoc direct calling of til_module_t.setup() they do presently.
2023-05-30til: find explicitly set experimental modulesVito Caputo
b9123bbb added describing incoming preexisting settings, but the spec's returned values omitted experimental modules. This resulted in breaking the ability to say things like --module=rkt to access the experimental rkt module despite it not showing in the interactive setup list of values. This commit includes experimental modules in the spec's values when being produced for a preexisting, undescribed setting. Restoring one's ability to access experimental modules via the CLI.
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-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-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_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: 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-11til: teach til_randomize_setup() about nested settingsVito Caputo
This probably needs more work, but it's good enough for now
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: 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-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-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-01-21modules/rocket: preliminary rocket moduleVito Caputo
This just stubs out a rocket meta module that renders with another module. Future commits will integrate GNU Rocket here. When recursive settings formally lands you'll be able to nest as much settings content as necessary for the underlying module used, as part of the rocket settings. That should enable describing stuff like complex compose scenarios for rocket to sequence.
© All Rights Reserved