Implemented the ability to copy/paste blocks/clips in the timeline. This did
require some large scale changes and reworking of the copy/paste system
introduced a few commits ago, but should be largely functional now.
Footage is a special case where the node parameters can reference objects that
exist outside of the graph. Therefore specific code is needed to
serialize/deserialize.
Since we load in a separate thread, when the QObject based objects are
instantiated, they're created with affinity to that separate thread. Now we
specifically ensure they are moved to the main thread after their creation.
If the nodes are now stateless, there's nothing stopping the renderer from
rendering multiple frames at once. Earlier since the nodes held some of their
input/output data (and that data could change per frame), it was not possible
to render multiple frames at once without conflicts. Now that the node state is
held in render threads, they can do whatever they want at any time.
If a NodeParam is destroyed (presumably as the result of its parent Node being
destroyed), any edge objects connecting to another param should be destroyed
or else the edge will be floating referencing a now destroyed object.
Old code assumes that a NodeParam's parent will always be a Node. The function
has been separated off and tweaked in the event that this is not the case.
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.