JUCE Slider value stores a scientific value when using referTo and using with ValueTree

Hi all,

I have a Slider and use referTo to have a property on a ValueTree automatically updated with the value. I.e.

mySlider.getValueObject().referTo (myValueTree.getPropertyAsValue ("MyParameter", nullptr));

This has worked for a long time, but since the last JUCE update (I think…) the property on the ValueTree is now storing scientific values.

E.g. If i put the Slider to the value ‘90’, the thing stored in the ValueTree is ‘9e1’, rather than ‘90’. If I set the slider to ‘1000’, it stores ‘1e3’.

When these values are picked up by the part of the code that needs to use them, the conversion to integers is now a bug in my code. It converts…

‘9e1’ -> ‘9’ (rather than ‘90’)
‘1e3’ -> ‘1’ (rather than ‘1000’)

Has something changed in JUCE to make this happen? If so, is this desirable default behaviour?

Thanks in advance!

Adam

There were some recent changes to how the decimals in strings are handled. It’s discussed some more in this thread:

It looks like the develop branch may have the correct code you’ll need?

1 Like

Or the latest commit from the master branch - I’ve cherry picked the serialisation changes across.

If things are still amiss then please post some code that reproduces the problem and we’ll fix it ASAP.

Thanks Tom. Having read the other thread I can see a few changes have been made. Is there a summary somewhere of what behaviour I should expect when serialising Strings?

:slight_smile:

You could look at the ValueTree unit tests here:

Thanks for this. I took a look at the unit tests.

There are some potential results from the scientific values that can be a bit strange depending on the way a value is set on a ValueTree. It means we have to be extra extra careful or we get strange results. For example, if i create a ValueTree:

ValueTree tree1 ("MyTestTree");

and then set a value as a double (using the example from the unit tests that becomes 1.234567e6):

tree1.setProperty ("Value", 1234567., nullptr);

and then I serialise this to XML…

ScopedPointer<XmlElement> xml (tree1.createXml());

producing a tree like this…

<MyTestTree Value="1.234567e6"/>

So then I de-serialise it into a new ValueTree…

ValueTree tree2 = ValueTree::fromXml (*xml);

and then attempt to recover the value to an integer:

int myValue = tree2["Value"];

and rather than taking the value ‘1234567’, the scientific notation of 1.234567e6 means that the integer is just ‘1’ (as it truncates the rest of the value).

Now, I know one might say “well you should have been more careful with your doubles and your ints - put the type you want on the ValueTree, not some other type!”

However, this is incredibly easy to do. Maybe in a very large JUCE application I might think, “I know, I want to control this parameter and I think I’ll use a Slider…”

Slider mySlider;
mySlider.setRange (0., 1234567.);
mySlider.getValueObject().referTo (tree1.getPropertyAsValue ("Value", nullptr));

and then later, in a totally different part of the codebase with some de-serialised tree…

int i = tree["Value"];

the resulting integer will take on all kinds of strange values when the scientific format is used.

So, my questions…

  1. Is this definitely desired behaviour? I totally accept that - used 100% correctly - the current implementation should work, however, a programmer might easily expect that the value 0.000006 stored on a ValueTree, serialised and then retrieved as an integer would result in truncation, making it 0. Instead, the current implementation would result in the value 6 - as the scientific notation of 6.0e-6 truncated produces 6.

  2. If the answer to question 1 is yes, what would you recommend as a foolproof way to get around this kind of situation? How should we retrieve values from the ValueTree, guaranteeing sensible behaviour without necessarily knowing the way that the value was set (as integer or double)?

Thanks,

Adam