ValueTree - finding the index of a removed child

Hi all,

I have had a good look on the forum and couldn’t find anything on this, so here’s a question.

I am working with Juce and using the ValueTree callbacks to update various parts of my program. In one or two cases, the child nodes represent some objects that I have stored in an array. When a child is removed, the callback is:

void valueTreeChildRemoved (ValueTree& parent, ValueTree& removedChild)

which doesn’t tell me the index of the removedChild node (at least, the index it was at before it was removed), this would be handy so that I can remove the corresponding element from my array. If I ask for:

parent.indexOf(removedChild)

I get -1, which makes perfect sense, as the child is no longer a node of the parent. And definitely I see the problems with providing an index for something that is no longer in the tree. However, it would be very handy if the callback was something like…

void valueTreeChildRemoved (ValueTree& parent, ValueTree& removedChild, int indexOfTheChildBeforeItWasRemoved)

At present - I have to destroy my entire array and re-populate it from the whole tree, which is inefficient. It’d be much better if I knew which node to remove and could remove it in isolation.

Many thanks in advance for any help!

Adam
:smiley:

Haven’t got an easy answer for that, but trying to keep another array in-sync with a ValueTree seems like the wrong way to do it… If you have data that needs to be mapped onto a particular child, surely you should make the data a property of that child? (e.g. by using a DynamicObject). Or by using a map rather than an array?

Hi Jules,

Thanks for your reply, and I’ll take a look at your suggestions.

There are a couple of bits where we will need (as far as I can tell) some kind of list/array of objects. For example, we have a list of devices connected to our software. Their parameters are properties of our ValueTree, but they also need to have existing object instantiations so that they can interact with the physical devices. They are currently stored in an array which is updated by ValueTree callbacks.

When a user deletes a device, it updates the ValueTree and the callback then doesn’t tell us which one it was. So we have to remove all devices and reconnect them all but the one that was removed, which would be nice to avoid.

It would be great if we could know which one was removed from the tree (and specifically its index) so we can disconnect/remove this device only.

Thanks for all your help,

Adam

Well you know which child has been removed so if your device class keeps an internal ValueTree which they are representing, you can cycle through your array and compare the removed tree to the tree each one holds. When you find a match you know that is the object that needs to be removed from your array.

This way your array won’t need to be kept in sync with the parent tree child order (although it probably will be if you’re not re-ordering either).

An index sounds like a horrible way to keep track. You’ll never be able to change that order, or insert etc.

For a similar situation, I use a property - in your case, do something like:

myValueTreeObject->setProperty (“DeviceObjectIndex”, 1);

Then you can always get the index back when you need. Relying on position in the array seems risky to me.

Huh, I guess your next problem will be that you have a device array that you will now be changing, and all the other indices will change? Can you move to a more fault tolerant ID system?

Bruce