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

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

1 Like

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.

Maybe if CachedValue was WeakReferenceable we could get around that.

Like ValueWithDefault?

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

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

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

Sure, I’ll get these added.

2 Likes