2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
23 ==============================================================================
29 //==============================================================================
31 Represents a shared variant value.
33 A Value object contains a reference to a var object, and can get and set its value.
34 Listeners can be attached to be told when the value is changed.
36 The Value class is a wrapper around a shared, reference-counted underlying data
37 object - this means that multiple Value objects can all refer to the same piece of
38 data, allowing all of them to be notified when any of them changes it.
40 When you create a Value with its default constructor, it acts as a wrapper around a
41 simple var object, but by creating a Value that refers to a custom subclass of ValueSource,
42 you can map the Value onto any kind of underlying data.
44 Important note! The Value class is not thread-safe! If you're accessing one from
45 multiple threads, then you'll need to use your own synchronisation around any code
50 class JUCE_API Value final
53 //==============================================================================
54 /** Creates an empty Value, containing a void var. */
57 /** Creates a Value that refers to the same value as another one.
59 Note that this doesn't make a copy of the other value - both this and the other
60 Value will share the same underlying value, so that when either one alters it, both
63 Value (const Value
& other
);
65 /** Creates a Value that is set to the specified value. */
66 explicit Value (const var
& initialValue
);
68 /** Move constructor */
69 Value (Value
&&) noexcept
;
74 //==============================================================================
75 /** Returns the current value. */
78 /** Returns the current value. */
81 /** Returns the value as a string.
82 This is a shortcut for "myValue.getValue().toString()".
84 String
toString() const;
86 /** Sets the current value.
88 You can also use operator= to set the value.
90 If there are any listeners registered, they will be notified of the
91 change asynchronously.
93 void setValue (const var
& newValue
);
95 /** Sets the current value.
97 This is the same as calling setValue().
99 If there are any listeners registered, they will be notified of the
100 change asynchronously.
102 Value
& operator= (const var
& newValue
);
104 /** Move assignment operator */
105 Value
& operator= (Value
&&) noexcept
;
107 /** Makes this object refer to the same underlying ValueSource as another one.
109 Once this object has been connected to another one, changing either one
110 will update the other.
112 Existing listeners will still be registered after you call this method, and
113 they'll continue to receive messages when the new value changes.
115 void referTo (const Value
& valueToReferTo
);
117 /** Returns true if this object and the other one use the same underlying
120 bool refersToSameSourceAs (const Value
& other
) const;
122 /** Compares two values.
123 This is a compare-by-value comparison, so is effectively the same as
124 saying (this->getValue() == other.getValue()).
126 bool operator== (const Value
& other
) const;
128 /** Compares two values.
129 This is a compare-by-value comparison, so is effectively the same as
130 saying (this->getValue() != other.getValue()).
132 bool operator!= (const Value
& other
) const;
134 //==============================================================================
135 /** Receives callbacks when a Value object changes.
136 @see Value::addListener
138 class JUCE_API Listener
141 Listener() = default;
142 virtual ~Listener() = default;
144 /** Called when a Value object is changed.
146 Note that the Value object passed as a parameter may not be exactly the same
147 object that you registered the listener with - it might be a copy that refers
148 to the same underlying ValueSource. To find out, you can call Value::refersToSameSourceAs().
150 virtual void valueChanged (Value
& value
) = 0;
153 /** Adds a listener to receive callbacks when the value changes.
155 The listener is added to this specific Value object, and not to the shared
156 object that it refers to. When this object is deleted, all the listeners will
157 be lost, even if other references to the same Value still exist. So when you're
158 adding a listener, make sure that you add it to a Value instance that will last
159 for as long as you need the listener. In general, you'd never want to add a listener
160 to a local stack-based Value, but more likely to one that's a member variable.
164 void addListener (Listener
* listener
);
166 /** Removes a listener that was previously added with addListener(). */
167 void removeListener (Listener
* listener
);
170 //==============================================================================
172 Used internally by the Value class as the base class for its shared value objects.
174 The Value class is essentially a reference-counted pointer to a shared instance
175 of a ValueSource object. If you're feeling adventurous, you can create your own custom
176 ValueSource classes to allow Value objects to represent your own custom data items.
178 class JUCE_API ValueSource
: public ReferenceCountedObject
,
183 ~ValueSource() override
;
185 /** Returns the current value of this object. */
186 virtual var
getValue() const = 0;
188 /** Changes the current value.
189 This must also trigger a change message if the value actually changes.
191 virtual void setValue (const var
& newValue
) = 0;
193 /** Delivers a change message to all the listeners that are registered with
196 If dispatchSynchronously is true, the method will call all the listeners
197 before returning; otherwise it'll dispatch a message and make the call later.
199 void sendChangeMessage (bool dispatchSynchronously
);
202 //==============================================================================
204 SortedSet
<Value
*> valuesWithListeners
;
207 void handleAsyncUpdate() override
;
209 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ValueSource
)
213 //==============================================================================
214 /** Creates a Value object that uses this valueSource object as its underlying data. */
215 explicit Value (ValueSource
* valueSource
);
217 /** Returns the ValueSource that this value is referring to. */
218 ValueSource
& getValueSource() noexcept
{ return *value
; }
222 //==============================================================================
223 friend class ValueSource
;
224 ReferenceCountedObjectPtr
<ValueSource
> value
;
225 ListenerList
<Listener
> listeners
;
227 void callListeners();
228 void removeFromListenerList();
230 // This is disallowed to avoid confusion about whether it should
231 // do a by-value or by-reference copy.
232 Value
& operator= (const Value
&) = delete;
234 // This declaration prevents accidental construction from an integer of 0,
235 // which is possible in some compilers via an implicit cast to a pointer.
236 explicit Value (void*) = delete;
239 /** Writes a Value to an OutputStream as a UTF8 string. */
240 OutputStream
& JUCE_CALLTYPE
operator<< (OutputStream
&, const Value
&);