ValueTree Request(s)


#1

Hey Jules

Is it sensible to add a removeAllListeners to ValueTree?

[EDIT]

or maybe removeAllListeners (bool alsoRemoveChildListeners = false)


#2

I think that’d be a Bad Design.

When you have a ValueTree, you never know how many other objects might be sharing the same value, or what they might be doing with it. It could easily break their functionality if another part of the code could randomly turn off their listeners.

Obviously sometimes you’ll write code where it would be safe to call such a function, but it’d really just be a lazy alternative to managing your listeners correctly.


#3

That’s why I ask… Just ran into a couple of occasions when I needed to remove all listeners without knowing who they were…

YES!

By the way I’ve been working with the ValueTree for a couple of weeks now, and it is just great!

Doing a little editor with it, for a plug-in, and it works very well to store/restore the plug-in state UI. Perfect UI/Processor separation. Also finding myself making some custom listeners by wrapping the value tree etc. Haven’t taken advantage of the Undo/Redo business yet though.

Great job!


#4

I’ve got another really cool class coming soon too, just called “Value”.

This will hold a shared variant, and lets you attach listeners to it. I’m going to use it in existing classes like the Slider to hold its value, so that you can do things like: create a Value object, then connect several sliders to it, so that your Value and the sliders will all move in sync.

It’ll also be possible to ask a ValueTree to give you a Value object that represents one of its properties. So e.g. to connect a slider’s position to the value of a property of your tree will be one line of code.


#5

Nice nice!

Can’t wait…

Can you add an option to “Value” to set whether or not its messages are sent to its listeners on the message thread? Would be nice for ValueTree too. So far all my ValueTree properties are set via buttons, sliders etc., so haven’t needed the callbacks to be asynchronous yet, but it might be a cool one when a thread builds up a tree with some values and a component might need to respond visually in some way. Just a thought.


#6

Yep, I’m just figuring out the best way to do that at the moment.


#7

Hey Jules

Some of the new ValueTree changes broke my code just a bit…

Before I was able to do this and my valueTreePropertyChanged would get called.

[code]ValueTree* instrumentTree = ownerFilter->getValueTree(); // Main ValueTree

for (int i = 0; i < instrumentTree->getNumChildren(); ++i)
{
instrumentTree->getChild (i).addListener (this);
}[/code]

Now it doesn’t seem to be working.

Getting a pointer to the actual ValueTree directly works, have to jump through a couple of more hoops though…

[code]ValueTree* instrumentTree = ownerFilter->getValueTree();

for (int i = 0; i < instrumentTree->getNumChildren(); i++)
{
ValueTree instElement = instrumentTree->getChild (i);

int32 nodeId = instElement.getProperty ("NodeID");

InstrumentProcessor* proc = ownerFilter->getInstrument (nodeId);

proc->getValueTree()->addListener (this);

}[/code]

I dont seem to get it, that ValueTree is a child of the main “instrumentTree”.

BTW
Thanks for the quick Wrapper tpo fix, that threw me off a little.


#8

Yes, listeners now work slightly differently. Originally I added all the listeners to the shared object that a ValueTree references. I’ve changed it now so that each ValueTree object has its own listeners, which only last as long as that ValueTree object. Because in your example you’re adding them to temporary ValueTree, your listeners are being lost as soon as the temporary object is deleted.

The reason I did this was because it was too easy to leave a dangling listener if you did something like this:

ValueTree a; a.addListener (this); ... a = otherValueTree; a.removeListener (this); //doesn't work! We're no longer registered to 'a' and can't de-register ourselves with any other copies of 'a' that might still be out there somewhere!

In the new version, the code above would be perfectly ok.

I used the same pattern for Value listeners, too.

It just means that you need to keep a ValueTree in existence for the same lifetime as its listeners, probably as a member variable. It seems a bit more restrictive, but is a much safer design!