Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

242 lines
5.6KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2020 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 6 End-User License
  8. Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
  9. End User License Agreement: www.juce.com/juce-6-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. Value::ValueSource::ValueSource()
  21. {
  22. }
  23. Value::ValueSource::~ValueSource()
  24. {
  25. cancelPendingUpdate();
  26. }
  27. void Value::ValueSource::handleAsyncUpdate()
  28. {
  29. sendChangeMessage (true);
  30. }
  31. void Value::ValueSource::sendChangeMessage (const bool synchronous)
  32. {
  33. const int numListeners = valuesWithListeners.size();
  34. if (numListeners > 0)
  35. {
  36. if (synchronous)
  37. {
  38. const ReferenceCountedObjectPtr<ValueSource> localRef (this);
  39. cancelPendingUpdate();
  40. for (int i = numListeners; --i >= 0;)
  41. if (Value* const v = valuesWithListeners[i])
  42. v->callListeners();
  43. }
  44. else
  45. {
  46. triggerAsyncUpdate();
  47. }
  48. }
  49. }
  50. //==============================================================================
  51. class SimpleValueSource : public Value::ValueSource
  52. {
  53. public:
  54. SimpleValueSource()
  55. {
  56. }
  57. SimpleValueSource (const var& initialValue)
  58. : value (initialValue)
  59. {
  60. }
  61. var getValue() const override
  62. {
  63. return value;
  64. }
  65. void setValue (const var& newValue) override
  66. {
  67. if (! newValue.equalsWithSameType (value))
  68. {
  69. value = newValue;
  70. sendChangeMessage (false);
  71. }
  72. }
  73. private:
  74. var value;
  75. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SimpleValueSource)
  76. };
  77. //==============================================================================
  78. Value::Value() : value (new SimpleValueSource())
  79. {
  80. }
  81. Value::Value (ValueSource* const v) : value (v)
  82. {
  83. jassert (v != nullptr);
  84. }
  85. Value::Value (const var& initialValue) : value (new SimpleValueSource (initialValue))
  86. {
  87. }
  88. Value::Value (const Value& other) : value (other.value)
  89. {
  90. }
  91. Value::Value (Value&& other) noexcept
  92. {
  93. // moving a Value with listeners will lose those listeners, which
  94. // probably isn't what you wanted to happen!
  95. jassert (other.listeners.size() == 0);
  96. other.removeFromListenerList();
  97. value = std::move (other.value);
  98. }
  99. Value& Value::operator= (Value&& other) noexcept
  100. {
  101. // moving a Value with listeners will lose those listeners, which
  102. // probably isn't what you wanted to happen!
  103. jassert (other.listeners.size() == 0);
  104. other.removeFromListenerList();
  105. value = std::move (other.value);
  106. return *this;
  107. }
  108. Value::~Value()
  109. {
  110. removeFromListenerList();
  111. }
  112. void Value::removeFromListenerList()
  113. {
  114. if (listeners.size() > 0 && value != nullptr) // may be nullptr after a move operation
  115. value->valuesWithListeners.removeValue (this);
  116. }
  117. //==============================================================================
  118. var Value::getValue() const
  119. {
  120. return value->getValue();
  121. }
  122. Value::operator var() const
  123. {
  124. return value->getValue();
  125. }
  126. void Value::setValue (const var& newValue)
  127. {
  128. value->setValue (newValue);
  129. }
  130. String Value::toString() const
  131. {
  132. return value->getValue().toString();
  133. }
  134. Value& Value::operator= (const var& newValue)
  135. {
  136. value->setValue (newValue);
  137. return *this;
  138. }
  139. void Value::referTo (const Value& valueToReferTo)
  140. {
  141. if (valueToReferTo.value != value)
  142. {
  143. if (listeners.size() > 0)
  144. {
  145. value->valuesWithListeners.removeValue (this);
  146. valueToReferTo.value->valuesWithListeners.add (this);
  147. }
  148. value = valueToReferTo.value;
  149. callListeners();
  150. }
  151. }
  152. bool Value::refersToSameSourceAs (const Value& other) const
  153. {
  154. return value == other.value;
  155. }
  156. bool Value::operator== (const Value& other) const
  157. {
  158. return value == other.value || value->getValue() == other.getValue();
  159. }
  160. bool Value::operator!= (const Value& other) const
  161. {
  162. return value != other.value && value->getValue() != other.getValue();
  163. }
  164. //==============================================================================
  165. void Value::addListener (Value::Listener* listener)
  166. {
  167. if (listener != nullptr)
  168. {
  169. if (listeners.size() == 0)
  170. value->valuesWithListeners.add (this);
  171. listeners.add (listener);
  172. }
  173. }
  174. void Value::removeListener (Value::Listener* listener)
  175. {
  176. listeners.remove (listener);
  177. if (listeners.size() == 0)
  178. value->valuesWithListeners.removeValue (this);
  179. }
  180. void Value::callListeners()
  181. {
  182. if (listeners.size() > 0)
  183. {
  184. Value v (*this); // (create a copy in case this gets deleted by a callback)
  185. listeners.call ([&] (Value::Listener& l) { l.valueChanged (v); });
  186. }
  187. }
  188. OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const Value& value)
  189. {
  190. return stream << value.toString();
  191. }
  192. } // namespace juce