LockingValueTreePropertyValueSource - code review..?


#1

Can anyone suggest ways in which this is flawed? It’s to allow me to pass some Values back-ended on a ValueTree around without worrying about which thread they are being used on. All other accesses to the ValueTree are protected with the same ReadWriteLock.

struct LockingValueTreePropertyValueSource : Value::ValueSource, private ValueTree::Listener
{
    LockingValueTreePropertyValueSource (const ValueTree& vt, const Identifier& prop, UndoManager* um, bool sync, std::shared_ptr<ReadWriteLock> lock)
        : tree (vt), property (prop), undoManager (um), updateSynchronously (sync), lock(std::move(lock))
    {
        if (lock != nullptr)
            lock->enterWrite(); 

        tree.addListener (this);

        if (lock != nullptr)
            lock->exitWrite(); 
    }

    ~LockingValueTreePropertyValueSource()
    {
        if (lock != nullptr)
            lock->enterWrite(); 

        tree.removeListener (this);

        if (lock != nullptr)
            lock->exitWrite(); 
    }

    var getValue() const override
    {
        if (lock != nullptr)
            lock->enterRead(); 

        auto v = tree[property];

        if (lock != nullptr)
            lock->exitRead(); 

        return v;
    }

    void setValue (const var& newValue) override
    {
        if (lock != nullptr)
            lock->enterWrite(); 

        tree.setProperty (property, newValue, undoManager);

        if (lock != nullptr)
            lock->exitWrite(); 
    }

private:
    ValueTree tree;
    const Identifier property;
    UndoManager* const undoManager;
    const bool updateSynchronously;
    std::shared_ptr<ReadWriteLock> lock;

    void valueTreePropertyChanged (ValueTree& changedTree, const Identifier& changedProperty) override
    {
        if (tree == changedTree && property == changedProperty)
            sendChangeMessage (updateSynchronously);
    }

    void valueTreeChildAdded (ValueTree&, ValueTree&) override {}
    void valueTreeChildRemoved (ValueTree&, ValueTree&, int) override {}
    void valueTreeChildOrderChanged (ValueTree&, int, int) override {}
    void valueTreeParentChanged (ValueTree&) override {}

    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LockingValueTreePropertyValueSource)
};