ValueTree Listeners and Move-Ctor

Hi everyone,
I’d be very glad if someone could give me a fresh perspective if I’m doing something wrong with my ValueTrees or if I’m expecting the correct behaviour from JUCE but it doesn’t deliver.

- (void) test_valueTree_listener_base_in_vector
{
  DECLARE_Spy_Listener_Explicit(ValueTree::Listener, valueTreePropertyChanged) listener;
  
  std::vector<ValueTree> valueTrees;
  valueTrees.push_back(ValueTree("TEST"));
  valueTrees[0].addListener(&listener);
  
  valueTrees.resize(10);
  valueTrees[0].setProperty("MyProp", "MyVal", nullptr);
  XCAssertTrue(listener.__methodWasCalled);
}

The above test case is failing. Even though I’m attaching my ValueTree listener to the reference in the std::vector, I’m not receiving the callback when the property changes. The problematic line is valueTrees.resize(10);. By that, the std::vector is being resized and the ValueTree objects are recreated. Since the move-ctor is marked noexcept, this one should be used. The resize statement for the vector is just a placeholder for any size changing operation. Adding/Removing elements from the vector that trigger the internal resize of the allocated RAM are all triggering this behaviour.

To fix this, the ListenerList would have to be moved into the new object. Is that something, that is recommended to be changed in JUCE or does that have side affects, that I don’t have the foresight for?

Best, Rincewind

I think this is expected behaviour, and is consistent with the docs for addListener:

Thanks for getting back to me! If that is the intended behavior, how would you suggest I implement a list like above? I think the main problem is, that this is allowed. Is it possible to generate a compiler error for using ValueTree in SRD::vector? It took me some time to figure out, why this is not working.

You could use std::vector<std::unique_ptr<ValueTree>>, or std::list<ValueTree>, both of which won’t attempt to move ValueTree instances when the container is resized.

Thanks, great tip!!!