The advantage of having a snapshot-based high-level node-set: The user isn't forced to build trees.
Here two different paints got described by an object graph.
Implementation
Clone-based
Build a new type that
has all the properties of the original type
wraps an instance of the original type within
Process-Node Setters: Whenever any input of the node changed...
Clone the incoming wrapped instance
Apply the local changes
Output a new snapshot - a new instance of the immutable type - holding the cloned and adjusted mutable instance
Consuming nodes that call further into the library simply ask for the original wrapped instance
Summary
This solution is high-level and versatile. The user has a large degree of freedom. The patches are readable so that no special UI is needed. Low-level nodes that work with the original type are barely needed as all the properties got wrapped by high-level Setter process nodes. Theoretically we still could expose the low-level nodes and make the snapshots expose the wrapped original instance in order to glue to those low-level nodes.
The implementation has the downside that whenever any property is animated we end up cloning instances of the original type all the time.
Sync-based
Build a new type that
has all the properties of the original type
does NOT wrap the original type
This new type could be patched as a record, with getters and setters for each property
Sinks manage the lifetime of one mutable instance of the original type and let it mutate over time by syncing to the incoming descriptions
Syncing only has to be done when the description changes, which is easily detectable. We can just ask whether the reference changed.
However whenever something changed we need to compare the latest synced snapshot with the current snapshot in order to find out which properties need to be set on the mutating living originally typed instance.
Another option would be to compare the properties of the incoming snapshot with the properties of the living thing, which is only different when we expose other ways of mutating the managed instance from downstream via low-level nodes. So if we need the ability to imperatively mutate the managed instance also with low-level nodes from downstream then
it is safer to compare to the property of the actual thing and setting the property if it is not equal to the incoming description
it might be more expensive, depending on the implementation of the property getters of the original type
Summary
Same advantages as the solution above.
The implementation has the downside that whenever any property is animated we end up comparing all properties on all sinks in order to synchronize the description with the actual thing.
A solution for https://github.com/vvvv/VL-Language/issues/30
The advantage of having a snapshot-based high-level node-set: The user isn't forced to build trees. Here two different paints got described by an object graph.
Implementation
Clone-based
Summary
This solution is high-level and versatile. The user has a large degree of freedom. The patches are readable so that no special UI is needed. Low-level nodes that work with the original type are barely needed as all the properties got wrapped by high-level Setter process nodes. Theoretically we still could expose the low-level nodes and make the snapshots expose the wrapped original instance in order to glue to those low-level nodes.
The implementation has the downside that whenever any property is animated we end up cloning instances of the original type all the time.
Sync-based
Summary
Same advantages as the solution above.
The implementation has the downside that whenever any property is animated we end up comparing all properties on all sinks in order to synchronize the description with the actual thing.