Age | Commit message (Collapse) | Author |
|
First stab at supporting explicit aspect ratios.
This performs the adjustment when needed in til_fb so it's
automatically applied to all fb backends.
The syntax is ratio=W:H with ratio=full being special cased for
when no aspect ratio adjustment is desired (just use whatever the
fb page dimensions are, usually specified via size= in the fb
backend's settings, or display native res when fullscreen=on)
For now when an aspect ratio is specified it always fits the
content within the alotted space... there is no
full-but-ratio-preserved-by-clipping-if-needed variant like widescreen
TVs often have.
|
|
Preparatory commit for aspect ratio settings at the fb layer.
This slightly reworks how main::setup_video() integrates the
selected fb backend's setup_func to better resemble how the
module setup_funcs work now, with more clearly separated
settings-building and setup-baking/finalizing phases. Which
makes inserting the ratio setting in the middle of the front-end
and back-end setup_funcs fairly trivial.
Not a fan of all the casts, but there will probably be more
helpers introduced to take care of that and make
til_video_setup_t more of a first-class thing facilitating the fb
stuff.
|
|
Instead of just calling til_module_render() with the top-level
module context, use the newly added til_stream_render() and
til_stream_set_module_context() to achieve the same thing.
This is a preparatory commit for handling pre/post-render module
contexts automagically in til_stream_render(). e.g. stuff like
background music would be hooked into the stream as a pre-render
context.
|
|
Until now everything interested in audio just used a plain getter
on the stream to get at the context.
But with how things work currently, audio is always left in a
paused state until explicitly unpaused. This works fine with
modules/rkt, which manages pause/unpause explicitly. When
there's nothing like modules/rkt in charge though, the audio just
sits stuck paused. Meaning if you do some simple thing like
--module=playit, it won't ever get unpaused.
With this commit, something like modules/rkt takes control of the
stream's audio context, in a way that prevents anything else from
taking control of the same context on the same stream. That
enables having main try take control of the audio context after
creating the module contexts, then in the rendering thread ensure
the audio is unpaused if main is in control of the audio context
and something's queueing audio frames.
For now there's no mechanism for releasing control of the audio
context. It doesn't seem appropriate to make this more elaborate
than necessary. There's basically just two use cases WRT audio:
1. Something like rkt, which takes control once for the process
and stays in control until process exit.
2. Something far simpler where nothing's taking control like
rkt, and main just needs to get things unpaused when
needed because something's generating audio frames.
|
|
Preliminary means of making the audio context available to
modules.
|
|
This is an early implementation of something resembling an audio
backend for rototiller/libtil.
The assumption for now is that everything will use signed 16-bit
native-endian stereo output @ 44.1khz.
|
|
Outside of overflow (which I'm ignoring for now) ticks shouldn't
go backwards. With the introduction of adding the frame-buffer
delays, which vary, there's the potential for the delay to go
from large to short in quick succession, to such a degree that
the next render's now+delay is in the past relative to the
previous now+delay.
For now this simple fix is to just track the last_ticks and
always use the maximum of the last_ticks and now+delay, ensuring
it never goes backwards.
This was making alphazed exit prematurely at spurious times by
sending the rocket_row into oblivion because (ticks - last_ticks)
was negative w/unsigned arithmetic. This will all get more work,
and maybe ticks should be allowed to go backwards actually, but
some things are assuming that's not the case as-is.
Regardless, it's not desirable for ticks to go backwards because
of the frame-buffer delay. In that case just chill on the ticks
advancement for a frame. This will need revisiting for sure, as
I don't think re-rendering the exact same tick as the last frame
is likely to be what's wanted either. Probably some little
advancement should still be performed...
|
|
This should push the ticks value ahead by 1-2 frames worth of
time, when rendering is meeting/exceeding the frame rate. Which
is the appropriate thing to do, since rendering is effectively
slightly ahead of the clock, producing visuals for now+N-frames
into the future.
When rendering lags behind, there's basically no delay, and
rendering is just operating on the "now" ticks which will be
flipped to ASAP once submitted.
This will probably be revisited once audio is rolled in, since
that too will need to be kept in sync with the visuals'
perspective of time.
|
|
til_fb is triple buffered, but when rendering lags behind the
queue is empty making present-to-delay intervals smaller than
when rendering is keeping up and the queue is kept full.
This returns the duration of the returned pages last
submit-to-present delay, effectively measuring how long a page
can expect to wait to be flipped to/presented currently.
A subsequent commit will apply this delay value to the ticks
supplied to rendering.
|
|
This was made redundant by til_ticks_now(), and get_ticks() looks
buggy in its usecs arithmetic on top of it.
|
|
Tell the stream when starting a new frame...
|
|
more cleaning up stuff on exit
|
|
This gets rid of the rototiller_thread() pthread_cancel() based
exit which seemed to rarely make clang's ASAN
(-fsanitize=address) very angry with a segfault in libc somewhere
Instead of trying to chase that down I'm just getting rid of it,
it's unnecessary.
|
|
This will just quietly exit successfully if "none" is provided as
the root rendering module.
It's not really a case worth bothering with doing something more
about... the user did this pointless thing on purpose. Let's just
not crash.
While here I may have fixed a bug surrounding til_quiesce() not
being called on the teardown path.
|
|
When introducing the **fragment_ptr model in 5a0776f, the
rototiller_thread() introduced a local place to put the pointer
to point at when rendering.
But this pointer then ends up outliving the thread on shutdown
within any queued frames until quiescent. Fixed in the obvious
way by sticking it in rototiller_t instead.
|
|
For meta-demo use cases like alphazed is experimenting with, it's
desirable to change the window title from "rototiller" to
"alphazed" or whatever if in windowed mode.
This adds a way to do that in the obvious fashion...
--title="alphazed" etc.
|
|
Returning the failed desc was just a lazy half-assed thing that
was sort of the best option in the simpler, pre-paths world.
But now that everything has paths thanks to recursive settings,
let's just return the path to the failed setting's desc.
This conveniently gets rid of a UAF bug when setup returned the
setting->desc as the failed desc, and main would print the desc
*after* freeing all the settings in its final moments.
But the best part is now more of the errors parsing settings
should be accompanied by an illuminatingly relevant setting path.
Previously you'd at best get a bare key from the desc, but often
no failed desc was returned at all and you saw no guidance at
all. But with the recent improvements to the setup error
handling I think those cases should be few if not entirely
eliminated.
|
|
I can't see this staying so simple for very long, but for now
this at least enables making rototiller-based rkt-sequenced demos
that exit gracefully when they're finished.
In a future where rtv may play embedded rkt configs+tracks, it
needs a way to detect the end of stream without making main exit.
But I'll cross that bridge when I get there...
|
|
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.
|
|
Some rudimentary instrumentation for monitoring the active module
contexts alongside the pipes
You probably want to redirect stderr to a file when using
--print-pipes and/or --print-module-contexts...
e.g.
```
rototiller --defaults --go --print-pipes --print-module-contexts 2>/dev/null
```
or, if you still want to monitor FPS or log_channels=on in rtv,
2>/file/to/tail then tail -F /file/to/tail in another terminal.
|
|
When all the stream encapsulated were pipes/taps, naming was less
precise. With module contexts in the process of being registered
in the stream, there's a need to distinguish things more.
This is a largely mechanical naming change...
|
|
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()
|
|
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.
|
|
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.
|
|
Preparatory for constructing unique paths from a given
setting/settings instance by walking up the tree
|
|
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.
|
|
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).
|
|
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.
|
|
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.
|
|
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.
|
|
This turns --print-pipes into a more top-like display. Redirect
the FPS on stderr somewhere else to get less flickering
e.g. 2>/dev/null
pipes print to stdout.
|
|
This was mostly done out of convenience at the expense of turning
the fragment struct into more of a junk drawer.
But properly cleaning up owned stream pipes on context destroy
makes the inappropriateness of being part of til_fb_fragment_t
glaringly apparent.
Now the stream is just a separate thing passed to context create,
with a reference kept in the context for use throughout. Cleanup
of the owned pipes on the stream supplied to context create is
automagic when the context gets destroyed.
Note that despite there being a stream in the module context, the
stream to use is still supplied to all the rendering family
functions (prepare/render/finish) and it's the passed-in stream
which should be used by these functions. This is done to support
the possibility of switching out the stream frame-to-frame, which
may be interesting. Imagine doing things like a latent stream
and a future stream and switching between them on the fly for
instance. If there's a sequencing composite module, it could
flip between multiple sets of tracks or jump around multiple
streams with the visuals immediately flipping accordingly.
This should fix the --print-pipes crashing issues caused by lack
of cleanup when contexts were removed (like rtv does so often).
|
|
This is a rudimentary integration of the new til_stream_t into
rototiller. If the stream is going to continue living in
til_fb_fragment_t, the fragmenters and other nested frame
scenarios likely need to be updated to copy the stream through to
make the pipes available to the nested renders.
--print-pipes dumps the values found at the pipes' driver taps
to stdout on every frame.
Right now there's no way to externally write these values, but
with --print-pipes you can already see where things are going and
it's a nice visibility tool for tapped variables in modules.
Only stars and plato tap variables presently, but that will
improve.
|
|
With --print-pipes there will be a potential shitload of stuff
getting printed out, and it'd be nice to easily distinguish that
content from the FPS counter.
Since stderr is normally less buffered than stdout (line
buffered) not lose debugging information, just put the
low-bandwidth periodic FPS print there instead. This leaves
stdout for --print-pipes output which occurs every frame *and*
may have a lot of content per print.
|
|
Particularly for simple boolean args it's desirable to just
access their values directly in the args without any further
cooking required. Rather than pointlessly duplicating those
cases, just give visibility into the raw args.
|
|
There needs to be a way to address module context instances
by name externally, in a manner complementary to settings and
taps.
This commit adds a string-based path to til_module_context_t, and
modifies til_module_create_context() to accept a parent path
which is then concatenated with the name of the module to produce
the module instance's new path.
The name separator used in the paths is '/' just like filesystem
paths, but these paths have no relationship to filesystems or
files.
The root module context creation in rototiller's main simply
passes "" as the parent path, resulting in a "/" root as one
would expect.
There are some obvious complications introduced here however:
- checkers in particular creates a context per cpu, simply using
the same seed and setup to try make the contexts identical at
the same ticks value. With this commit I'm simply passing the
incoming path as the parent for creating those contexts, but
it's unclear to me if that will work OK. With an eye towards
taps deriving their parent path from the context path, I guess
these taps would all get the same parent and hash to the same
value despite being duplicated. Maybe it Just Works, but one
thing is clear - there won't be any way to address the per-cpu
taps as-is. Maybe that's desirable though, there's probably
not much use in trying to control the taps at the CPU
granularity.
- when the recursive settings stuff lands, it should bring along
the ability to explicitly name settings blocks. Those names
should override the module name in constructing the path.
I've noted as such in the code.
- these paths probably need to be hashed @ initialization time
so there needs to be a hash function added to til, and a hash
value accompanying the name in the module context. It'd be
dumb to keep recomputing the hash when these paths get used
for hash table lookups multiple times per frame...
there's probably more I'm forgetting right now, but this seems
like a good first step.
fixup root path
|
|
Show the info, but skip the wait step.
|
|
It seems like it might be most ergonomic and convenient for
everything to just use til_fb_fragment_t and rely on ops.submit
to determine if the fragment is a page or not, and if it is how
to submit it.
This commit brings things into that state of the world, it feels
kind of gross at the til_fb_page_*() API. See the large comment
in til_fb.c added by this commit for more information.
I'm probably going to just run with this for now, it can always
get cleaned up later. What's important is to get the general
snapshotting concept and functionality in place so modules can
make use of it. There will always be things to cleanup in this
messy tangle of a program.
|
|
Preparatory commit for enabling cloneable/swappable fragments
There's an outstanding issue with the til_fb_page_t submission,
see comments. Doesn't matter for now since cloning doesn't happen
yet, but will need to be addressed before they do.
|
|
The purpose of printing the setup is to enable reproducing it,
the seed is part of that reconstruction - especially when it's
been autogenerated.
|
|
This enables reproducible yet pseudo-randomized visuals, at least
for the fully procedural modules.
The modules that are more simulation-y like sparkler and swarm
will still have runtime variations since they are dependent on
how much the simulation can run and there's been a lot of
sloppiness surrounding delta-t correctness and such.
But still, in a general sense, you'll find more or less similar
results even when doing randomized things like
module=rtv,channels=compose using the same seed value.
For the moment it only accepts a hexadecimal value, the leading
0x is optional.
e.g. these are all valid:
--seed=0xdeadbeef
--seed=0xdEAdBeFf
--seed=0x (produces 0)
--seed=0xff
--seed=deadbeef
--seed=ff
--seed= (produces 0)
--seed=0 (produces 0)
when you exceed the natural word size of an unsigned int on your
host architecture, an overflow error will be returned.
there are remaining issues to be fixed surrounding PRNG
reproducibility, in that things like til_module_randomize_setup()
doesn't currently accept a seed value. However it doesn't even
use rand_r() currently, but when it invokes desc->random() the
module's random() implementation should be able to use rand_r()
and needs to be fed the seed. So that all still needs wiring up
to propagate the root seed down everywhere it may be relevant.
|
|
Now that there's the mem_fb backend, there's no need to disable
producing a rototiller binary in lieu of libdrm and libsdl2.
This commit also rejiggers some of the DEFAULT_VIDEO junk in
main.c to ensure it falls back on "mem" should there be no drm or
sdl2.
For now I'm going to leave the AM_CONDITIONAL junk surrounding
enabling rototiller in configure.ac, the define can just be
ignored for now.
|
|
The immediate impetus for adding this is to enable running
rototiller even on headless machines just for the sake of getting
some FPS measurements.
It'd be nice to get a sense for what FPS rototiller would
experience on larger modern machines like big EPYC or
Threadripper systems. But it seems most of those I can get
access to via others running them on work hardware or the like
can at most just run it over ssh without any display or risk of
disrupting the physical console.
But this is probably also useful for testing/debugging purposes,
especially since it doesn't bother to synchronize flips on
anything not even a timer. So a bunch of display complexity is
removed running with video=mem as well as letting the framerate
run unbounded.
Having said that, it might be nice to add an fps=N setting where
mem_fb uses a plain timer for scheduling the flips.
Currently the only setting is size=WxH identical to the sdl_fb
size= setting, defaulting to 640x480.
|
|
Until now the fb init has been receiving a til_settings_t to
access its setup. Now that there's a til_setup_t for
representing the fully baked setup, let's bring the fb stuff
up to speed so their init() behaves more like
til_module_t.create_context() WRT settings/setup.
This involves some reworking of how settings are handled in
{drm,sdl}_fb.c but nothing majorly different.
The only real funcitonal change that happened in the course of
this work is I made it possible now to actually instruct SDL to
do a more legacy SDL_WINDOW_FULLSCREEN vs.
SDL_WINDOW_FULLSCREEN_DESKTOP where SDL will attempt to switch
the video mode.
This is triggered by specifying both a size=WxH and fullscreen=on
for video=sdl. Be careful though, I've observed some broken
display states when specifying goofy sizes, which look like Xorg
bugs.
|
|
- modules now allocate their contexts using
til_module_context_new() instead of [cm]alloc().
- modules simply embed til_module_context_t at the start of their
respective private context structs, if they do anything with
contexts
- modules that do nothing with contexts (lack a create_context()
method), will now *always* get a til_module_context_t supplied
to their other methods regardless of their create_context()
presence. So even if you don't have a create_context(), your
prepare_frame() and/or render_fragment() methods can still
access seed and n_cpus from within the til_module_context_t
passed in as context, *always*.
- modules that *do* have a create_context() method, implying they
have their own private context type, will have to cast the
til_module_context_t supplied to the other methods to their
private context type. By embedding the til_module_context_t at
the *start* of their private context struct, a simple cast is
all that's needed. If it's placed somewhere else, more
annoying container_of() style macros are needed - this is
strongly discouraged, just put it at the start of struct.
- til_module_create_context() now takes n_cpus, which may be set
to 0 for automatically assigning the number of threads in its
place. Any non-zero value is treated as an explicit n_cpus,
primarily intended for setting it to 1 for single-threaded
contexts necessary when embedded within an already-threaded
composite module.
- modules like montage which open-coded a single-threaded render
are now using the same til_module_render_fragment() as
everything else, since til_module_create_context() is accepting
n_cpus.
- til_module_create_context() now produces a real type, not void
*, that is til_module_context_t *. All the other module
context functions now operate on this type, and since
til_module_context_t.module tracks the module this context
relates to, those functions no longer require both the module
and context be passed in. This is especially helpful for
compositing modules which do a lot of module context creation
and destruction; the module handle is now only needed to create
the contexts. Everything else operating on that context only
needs the single context pointer, not module+context pairs,
which was unnecessarily annoying.
- if your module's context can be destroyed with a simple free(),
without any deeper knowledge or freeing of nested pointers, you
can now simply omit destroy_context() altogether. When
destroy_context() is missing, til_module_context_free() will
automatically use libc's free() on the pointer returned from
your create_context() (or on the pointer that was automatically
created if you omitted create_context() too, for the
bare til_module_context_t that got created on your behalf
anyways).
For the most part, these changes don't affect module creation.
In some ways this eases module creation by making it more
convenient access seed and n_cpus if you had no further
requirement for a context struct.
In other ways it's slightly annoying to have to do type-casts
when you're working with your own context type, since before it
was all void* and didn't require casts when assigning to your
typed context variables.
The elimination for requiring a destroy_context() method in
simple free() of private context scenarios removes some
boilerplate in simple cases.
I think it's a wash for module writers, or maybe a slight win for
the simple cases.
|
|
This commit improves the error printed when cli-supplied args
fail, adding at least the key name to what used to be just a
stringified errno:
```
$ src/rototiller --module=shapes,scale=99
Shape type:
0: circle
1: pinwheel
2: rhombus
3: star
Enter a value 0-3 [1 (pinwheel)]:
Fatal error: unable to use args for setting "scale": Invalid argument
$
```
|
|
In rototiller this disables the automatic displaying of settings
actually used when they differ from what was explicitly specified
as args. Which also disables the waiting to press a key.
This should also get used by glimmer to automatically start
rendering without just putting up the configured settings panel
and waiting for a click on "go!".
|
|
I don't think rototiller is an appropriate place for being so
uncooperative, if someone gets the case wrong anywhere just make
it work. We should avoid making different things so subtly
different that case alone is the distinction anyways, so I don't
see this creating any future namespace collision problems.
|
|
In the recent surge of ADD-style rtv+compose focused development,
a bunch of modules were changed to randomize initial states at
context_create() so they wouldn't be so repetitive.
But the way this was done in a way that made it impossible to
suppress the randomized initial state, which sometimes may be
desirable in compositions. Imagine for instance something like
the checkers module, rendering one module in the odd cells, and
another module into the even cells. Imagine if these modules are
actually the same, but if checkers used one seed for all the odd
cells and another seed for all the even cells. If the modules
used actually utilized the seed provided, checkers would be able
to differentiate the odd from even by seeding them differently
even when the modules are the same.
This commit is a step in that direction, but rototiller and all
the composite modules (rtv,compose,montage) are simply passing
rand() as the seeds. Also none of the modules have yet been
modified to actually make use of these seeds.
Subsequent commits will update modules to seed their
pseudo-randomized initial state from the seed value rather than
always calling things like rand() themselves.
|
|
This brings something resembling an actual type to the private
objects returrned in *res_setup. Internally libtil/rototiller
wants this to be a til_setup_t, and it's up to the private users
of what's returned in *res_setup to embed this appropriately and
either use container_of() or casting when simply embedded at the
start to go between til_setup_t and their private containing
struct.
Everywhere *res_setup was previously allocated using calloc() is
now using til_setup_new() with a free_func, which til_setup_new()
will initialize appropriately. There's still some remaining work
to do with the supplied free_func in some modules, where free()
isn't quite appropriate.
Setup freeing isn't actually being performed yet, but this sets
the foundation for that to happen in a subsequent commit that
cleans up the setup leaks.
Many modules use a static default setup for when no setup has
been provided. In those cases, the free_func would be NULL,
which til_setup_new() refuses to do. When setup freeing actually
starts happening, it'll simply skip freeing when
til_setup_t.free_func is NULL.
|