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)
};