I have a large app which contains many many value trees, when copying their state from presets on disk, most time is spent calling listener callbacks. In this case, I’d like to skip calling change messages on the listeners.
Would it be possible to do like:
copyPropertiesAndChildren(source, undo, NotificationType)
I’d also be very interested in expanding the ValueTree API a little bit. But could you add more information on how this is useful and what the followup would be? Do you want no notifications to be sent and how would the rest of your app then know that the ValueTree changed?
I always find wanting to mess with the listener mechanism a bit of a code smell - if you’re registered as a listener it’s because you want to know when things change so you can act accordingly, if another client somewhere is blocking those callbacks from happening then how do they know what the side effects might be?
For this particular use case, I think I’d look at loading the presets to a new value tree and then reassigning the existing tree, rather than setting each individual property.
I’m totally with you on the code smell! In my particular case, I was hooking up a ValueTreeSynchroniser for a bi directional connection between two ValueTrees (over network) and it was quiet the hassle because I was not able to exclude the upstream listener from the changes (which would result in a loop).
Concerning the redirection: I found this mechanic to be rather hindering me (in a sense of endless debugging hours because JUCE did stuff I didn’t want) than useful. E.g. I have a ValueTree structure that is looked at by multiple UI components. When I redirect the ValueTree in one place, all other UI elements are still showing the original data.
We’ll I just suggest this a approach since it’s already widely used with the listener patterns in the codebase with buttons and components
As far as I can tell there is no way to copy a valuetrees state without calling listener callbacks for every property in the tree.
Even without any listeners connected to the tree, it burns just doing the checks. On my M1 I don’t even notice it, but I see a bit of slowdown on older / slower machines doing a bunch of check.
I haven’t tried valuetree redirected maybe the copy constructor behaves differently
Copy constructor doesn’t work, just copyPropertiesAndChildren – it’s not code smell, it’s basic functionality.
There are thousands of properties not even visible on the screen, it’s not necessary to call change callbacks on all listeners in all cases.
As I understand the listeners aren’t the only problem as it also burns with out any attached? Could you maybe be a little more specific about what your performance tests measured?
@ImJimmi what would be a great addition for some of my code (and AFAI understand this is also a problem here): I’d like to be able to create a deep copy of a ValueTree as cheap and fast as possible. If you know you are creating a completely new component (in essentially one atomic operation as far as the ValueTree structure is concerned), there are probably a numerous of checks that can be left out. At the moment I always need to create an empty ValueTree and then copy properties and childs from the one to be cloned.
As a use case example: I’d like to off load as much of the IO operations as possible. And that means: copy the ValueTree, move the copy to the background thread, and on the background thread compile it into an XmlElement, then into a string, and then write to disk. If you could do a cheap ValueTree clone you can offload the XmlElement creation with a speed gain to the background thread.
Yes precisely, copyPropertiesAndChildren does a linear scale for loop over all the properties in the tree, as far as I can tell there’s no way to swap a value tree object. Ideally if notifications were off the valuetree wouldn’t use any loops at all to copy its tree state.
Maybe it’s possible to do some sort of hack by converting to xml and reloading from that state or something along those lines
If the ValueTree you want to replace has a parent, then you could simply remove the tree from its parent and add the new tree to the parent, because then you don’t get all the property change callbacks.
If the tree is the root, then redirect the tree.
Changing the parent is actually a pretty great idea, I haven’t thought of that before!!