Since rationals aren't a known Qt format, the QVariant container can't
automatically convert them to and from strings (for XML serialization). We have
to hijack these functions and do the conversion manually for those types.
Also moved the block name type to a node input, which means it's serialized
and copied by default (I'm not sure why it wasn't already like this).
This functions more or less identically to using a media out value, but the
desired speed is preserved through block length changes, even if the block's
length is reduced to zero (i.e. no rounding errors).
An earlier commit implementing media in and out parameters was primarily for
this addition. A simple control dialog for the clip's speed presentation
reimplemented from the old codebase.
Like the base "Block" type, the "Transition" type will not be a node used on its
own, it will have to be derived. This type defines some basic behavior for a
transition (e.g. how much it overlaps its "from" and "to" blocks).
If Nodes only have the one output, we don't need to do so much differentiation
between them. Previous iteration used outputs as like a distinct function
within a Node (e.g. length output would return one result, buffer output would
produce a different result - each run different code to produce their results).
Now in this iteration, it's more accurate to say a Node is just one function
(which seems more appropriate for a node system anyway).
Since the nodes won't be holding any rendering data themselves in this system,
we may as well enforce some level of non-write access by setting all the
functions to const. They were already const-friendly, they just weren't
labelled as such.
Fixes recurring design issue that the Blocks were a frequent exception to the
DAG concept. The Blocks connecting to each others inputs/outputs while not
necessarily being "dependent" on each other to produce an image continually
causes issues while trying to create a rendering code path. This redesign
should provide a more "directed" approach to the directed acyclic graph.
It was becoming inevitable to get rid of this, it was continuously an exception
that had to be made to the DAG concept seeing as blocks are never really
"dependents" on each other, i.e. the images they produce have nothing to do
with other blocks. The only exception is a transition which will also be
easier to accomplish with this slightly different design.
Previous iterations would use mutexes to prevent changing of the graph
mid-render, however several user actions would need to capture these mutexes
causing the main thread to hang until the current render job (frame/range of
samples) was complete. We now copy the nodes necessary as part of the "compile"
process so that the main thread shouldn't need nearly as much blocking while
caching occurs.
The new rendering pipeline strives to simplify the nodes themselves as much
as possible and move much of the logic to an external rendering engine. This
change removes all of the responsibilities that no longer belong to the
nodes themselves and will soon be folded into the renderer.
Nodes were previously written to be "strongly typed" in that a parameter's
"type" enforced whether it could be connected to another. All code related
to that has now been removed since not only is it hard to maintain and
likely unnecessary, it's possible the nodes will work differently later on
anyway.