/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
This file is part of the JUCE library .
Copyright ( c ) 2015 - ROLI Ltd .
Permission is granted to use this software under the terms of either :
a ) the GPL v2 ( or any later version )
b ) the Affero GPL v3
Details of these licenses can be found at : www . gnu . org / licenses
JUCE is distributed in the hope that it will be useful , but WITHOUT ANY
WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE . See the GNU General Public License for more details .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
To release a closed - source product which uses JUCE , commercial licenses are
available : visit www . juce . com for more information .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# ifndef JUCE_VALUE_H_INCLUDED
# define JUCE_VALUE_H_INCLUDED
//==============================================================================
/**
Represents a shared variant value .
A Value object contains a reference to a var object , and can get and set its value .
Listeners can be attached to be told when the value is changed .
The Value class is a wrapper around a shared , reference - counted underlying data
object - this means that multiple Value objects can all refer to the same piece of
data , allowing all of them to be notified when any of them changes it .
When you create a Value with its default constructor , it acts as a wrapper around a
simple var object , but by creating a Value that refers to a custom subclass of ValueSource ,
you can map the Value onto any kind of underlying data .
*/
class JUCE_API Value
{
public :
//==============================================================================
/** Creates an empty Value, containing a void var. */
Value ( ) ;
/** Creates a Value that refers to the same value as another one.
Note that this doesn ' t make a copy of the other value - both this and the other
Value will share the same underlying value , so that when either one alters it , both
will see it change .
*/
Value ( const Value & other ) ;
/** Creates a Value that is set to the specified value. */
explicit Value ( const var & initialValue ) ;
# if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
Value ( Value & & ) noexcept ;
Value & operator = ( Value & & ) noexcept ;
# endif
/** Destructor. */
~ Value ( ) ;
//==============================================================================
/** Returns the current value. */
var getValue ( ) const ;
/** Returns the current value. */
operator var ( ) const ;
/** Returns the value as a string.
This is a shortcut for " myValue.getValue().toString() " .
*/
String toString ( ) const ;
/** Sets the current value.
You can also use operator = to set the value .
If there are any listeners registered , they will be notified of the
change asynchronously .
*/
void setValue ( const var & newValue ) ;
/** Sets the current value.
This is the same as calling setValue ( ) .
If there are any listeners registered , they will be notified of the
change asynchronously .
*/
Value & operator = ( const var & newValue ) ;
/** Makes this object refer to the same underlying ValueSource as another one.
Once this object has been connected to another one , changing either one
will update the other .
Existing listeners will still be registered after you call this method , and
they ' ll continue to receive messages when the new value changes .
*/
void referTo ( const Value & valueToReferTo ) ;
/** Returns true if this value and the other one are references to the same value.
*/
bool refersToSameSourceAs ( const Value & other ) const ;
/** Compares two values.
This is a compare - by - value comparison , so is effectively the same as
saying ( this - > getValue ( ) = = other . getValue ( ) ) .
*/
bool operator = = ( const Value & other ) const ;
/** Compares two values.
This is a compare - by - value comparison , so is effectively the same as
saying ( this - > getValue ( ) ! = other . getValue ( ) ) .
*/
bool operator ! = ( const Value & other ) const ;
//==============================================================================
/** Receives callbacks when a Value object changes.
@ see Value : : addListener
*/
class JUCE_API Listener
{
public :
Listener ( ) { }
virtual ~ Listener ( ) { }
/** Called when a Value object is changed.
Note that the Value object passed as a parameter may not be exactly the same
object that you registered the listener with - it might be a copy that refers
to the same underlying ValueSource . To find out , you can call Value : : refersToSameSourceAs ( ) .
*/
virtual void valueChanged ( Value & value ) = 0 ;
} ;
/** Adds a listener to receive callbacks when the value changes.
The listener is added to this specific Value object , and not to the shared
object that it refers to . When this object is deleted , all the listeners will
be lost , even if other references to the same Value still exist . So when you ' re
adding a listener , make sure that you add it to a Value instance that will last
for as long as you need the listener . In general , you ' d never want to add a listener
to a local stack - based Value , but more likely to one that ' s a member variable .
@ see removeListener
*/
void addListener ( Listener * listener ) ;
/** Removes a listener that was previously added with addListener(). */
void removeListener ( Listener * listener ) ;
//==============================================================================
/**
Used internally by the Value class as the base class for its shared value objects .
The Value class is essentially a reference - counted pointer to a shared instance
of a ValueSource object . If you ' re feeling adventurous , you can create your own custom
ValueSource classes to allow Value objects to represent your own custom data items .
*/
class JUCE_API ValueSource : public ReferenceCountedObject ,
private AsyncUpdater
{
public :
ValueSource ( ) ;
virtual ~ ValueSource ( ) ;
/** Returns the current value of this object. */
virtual var getValue ( ) const = 0 ;
/** Changes the current value.
This must also trigger a change message if the value actually changes .
*/
virtual void setValue ( const var & newValue ) = 0 ;
/** Delivers a change message to all the listeners that are registered with
this value .
If dispatchSynchronously is true , the method will call all the listeners
before returning ; otherwise it ' ll dispatch a message and make the call later .
*/
void sendChangeMessage ( bool dispatchSynchronously ) ;
protected :
//==============================================================================
friend class Value ;
SortedSet < Value * > valuesWithListeners ;
private :
void handleAsyncUpdate ( ) override ;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR ( ValueSource )
} ;
//==============================================================================
/** Creates a Value object that uses this valueSource object as its underlying data. */
explicit Value ( ValueSource * valueSource ) ;
/** Returns the ValueSource that this value is referring to. */
ValueSource & getValueSource ( ) noexcept { return * value ; }
private :
//==============================================================================
friend class ValueSource ;
ReferenceCountedObjectPtr < ValueSource > value ;
ListenerList < Listener > listeners ;
void callListeners ( ) ;
void removeFromListenerList ( ) ;
// This is disallowed to avoid confusion about whether it should
// do a by-value or by-reference copy.
Value & operator = ( const Value & ) JUCE_DELETED_FUNCTION ;
// This declaration prevents accidental construction from an integer of 0,
// which is possible in some compilers via an implicit cast to a pointer.
explicit Value ( void * ) JUCE_DELETED_FUNCTION ;
} ;
/** Writes a Value to an OutputStream as a UTF8 string. */
OutputStream & JUCE_CALLTYPE operator < < ( OutputStream & , const Value & ) ;
/** This typedef is just for compatibility with old code - newer code should use the Value::Listener class directly. */
typedef Value : : Listener ValueListener ;
# endif // JUCE_VALUE_H_INCLUDED