CachedValue::getPropertyAsValue() doesn't take default into account


#1

CachedValue::getPropertyAsValue() doesn’t take default into account. Seems odd that CachedValue::get() and CachedValue::getPropertyAsValue().getValue() can return different values.


#2

Yeah, this is a bit of a pain.
There’s two ways to deal with it, one is to flush the default to the state before calling getPropertyAsValue.

The other that I haven’t’ tried is creating a custom ValueSource that returns the default if the property is missing. That’s fairly verbose though and could be error prone if the default it changed etc.


#3

Maybe if CachedValue was WeakReferenceable we could get around that.


#4

Like ValueWithDefault?


#5

Yeah but you’d still need to wrap that in a ValueSource to be able to attach it to a Slider or similar?


#6

Yeah there are a few ValueSource implementations in the property components, like the RemapperValueSourceWithDefault here.


#7

Here’s two possible implementations:

struct ValueSourceWithDefault   : public Value::ValueSource
{
    ValueSourceWithDefault (ValueTree& tree, const Identifier& propertyID, UndoManager* um, const var& defaultToUse)
        : value (tree, propertyID, um, defaultToUse)
    {}

    template<typename Type>
    ValueSourceWithDefault (const CachedValue<Type>& cachedValue, UndoManager* um)
        : ValueSourceWithDefault (cachedValue.getValueTree(), cachedValue.getPropertyID(), um, cachedValue.getDefault())
    {}

    var getValue() const override                   { return value.get(); }
    void setValue (const var& newValue) override    { value = newValue; }

    ValueWithDefault value;
};

and

template<typename Type>
struct CachedValueSource    : public Value::ValueSource
{
    CachedValueSource (ValueTree& tree, const Identifier& propertyID, UndoManager* um, const var& defaultToUse)
        : value (tree, propertyID, um, defaultToUse)
    {}

    CachedValueSource (const CachedValue<Type>& valueToUse, UndoManager* um)
        : value (valueToUse.getValueTree(), valueToUse.getPropertyID(), um, valueToUse.getDefault())
    {}

    var getValue() const override                   { return value.get(); }
    void setValue (const var& newValue) override    { value = newValue; }

    CachedValue<Type> value;
};

Requests:

  • Add a CachedValue::getUndoManager() method so we don’t have to pass this in the constructor. This seems like a simple omission.
  • Add a JUCE_DECLARE_WEAK_REFERENCEABLE to CachedValue so I don’t have to keep a copy of the CachedValue which will save a bit of listener overhead and means if the source default changes we can update it

#8

Sure, I’ll get these added.