The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

278 lines
7.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. NamedValueSet::NamedValue::NamedValue() noexcept
  19. {
  20. }
  21. inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, const var& value_)
  22. : name (name_), value (value_)
  23. {
  24. }
  25. NamedValueSet::NamedValue::NamedValue (const NamedValue& other)
  26. : name (other.name), value (other.value)
  27. {
  28. }
  29. NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (const NamedValueSet::NamedValue& other)
  30. {
  31. name = other.name;
  32. value = other.value;
  33. return *this;
  34. }
  35. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  36. NamedValueSet::NamedValue::NamedValue (NamedValue&& other) noexcept
  37. : nextListItem (static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem)),
  38. name (static_cast <Identifier&&> (other.name)),
  39. value (static_cast <var&&> (other.value))
  40. {
  41. }
  42. inline NamedValueSet::NamedValue::NamedValue (const Identifier& name_, var&& value_)
  43. : name (name_), value (static_cast <var&&> (value_))
  44. {
  45. }
  46. NamedValueSet::NamedValue& NamedValueSet::NamedValue::operator= (NamedValue&& other) noexcept
  47. {
  48. nextListItem = static_cast <LinkedListPointer<NamedValue>&&> (other.nextListItem);
  49. name = static_cast <Identifier&&> (other.name);
  50. value = static_cast <var&&> (other.value);
  51. return *this;
  52. }
  53. #endif
  54. bool NamedValueSet::NamedValue::operator== (const NamedValueSet::NamedValue& other) const noexcept
  55. {
  56. return name == other.name && value == other.value;
  57. }
  58. //==============================================================================
  59. NamedValueSet::NamedValueSet() noexcept
  60. {
  61. }
  62. NamedValueSet::NamedValueSet (const NamedValueSet& other)
  63. {
  64. values.addCopyOfList (other.values);
  65. }
  66. NamedValueSet& NamedValueSet::operator= (const NamedValueSet& other)
  67. {
  68. clear();
  69. values.addCopyOfList (other.values);
  70. return *this;
  71. }
  72. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  73. NamedValueSet::NamedValueSet (NamedValueSet&& other) noexcept
  74. : values (static_cast <LinkedListPointer<NamedValue>&&> (other.values))
  75. {
  76. }
  77. NamedValueSet& NamedValueSet::operator= (NamedValueSet&& other) noexcept
  78. {
  79. other.values.swapWith (values);
  80. return *this;
  81. }
  82. #endif
  83. NamedValueSet::~NamedValueSet()
  84. {
  85. clear();
  86. }
  87. void NamedValueSet::clear()
  88. {
  89. values.deleteAll();
  90. }
  91. bool NamedValueSet::operator== (const NamedValueSet& other) const
  92. {
  93. const NamedValue* i1 = values;
  94. const NamedValue* i2 = other.values;
  95. while (i1 != nullptr && i2 != nullptr)
  96. {
  97. if (! (*i1 == *i2))
  98. return false;
  99. i1 = i1->nextListItem;
  100. i2 = i2->nextListItem;
  101. }
  102. return true;
  103. }
  104. bool NamedValueSet::operator!= (const NamedValueSet& other) const
  105. {
  106. return ! operator== (other);
  107. }
  108. int NamedValueSet::size() const noexcept
  109. {
  110. return values.size();
  111. }
  112. const var& NamedValueSet::operator[] (const Identifier& name) const
  113. {
  114. for (NamedValue* i = values; i != nullptr; i = i->nextListItem)
  115. if (i->name == name)
  116. return i->value;
  117. return var::null;
  118. }
  119. var NamedValueSet::getWithDefault (const Identifier& name, const var& defaultReturnValue) const
  120. {
  121. const var* const v = getVarPointer (name);
  122. return v != nullptr ? *v : defaultReturnValue;
  123. }
  124. var* NamedValueSet::getVarPointer (const Identifier& name) const noexcept
  125. {
  126. for (NamedValue* i = values; i != nullptr; i = i->nextListItem)
  127. if (i->name == name)
  128. return &(i->value);
  129. return nullptr;
  130. }
  131. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  132. bool NamedValueSet::set (const Identifier& name, var&& newValue)
  133. {
  134. LinkedListPointer<NamedValue>* i = &values;
  135. while (i->get() != nullptr)
  136. {
  137. NamedValue* const v = i->get();
  138. if (v->name == name)
  139. {
  140. if (v->value.equalsWithSameType (newValue))
  141. return false;
  142. v->value = static_cast <var&&> (newValue);
  143. return true;
  144. }
  145. i = &(v->nextListItem);
  146. }
  147. i->insertNext (new NamedValue (name, static_cast <var&&> (newValue)));
  148. return true;
  149. }
  150. #endif
  151. bool NamedValueSet::set (const Identifier& name, const var& newValue)
  152. {
  153. LinkedListPointer<NamedValue>* i = &values;
  154. while (i->get() != nullptr)
  155. {
  156. NamedValue* const v = i->get();
  157. if (v->name == name)
  158. {
  159. if (v->value.equalsWithSameType (newValue))
  160. return false;
  161. v->value = newValue;
  162. return true;
  163. }
  164. i = &(v->nextListItem);
  165. }
  166. i->insertNext (new NamedValue (name, newValue));
  167. return true;
  168. }
  169. bool NamedValueSet::contains (const Identifier& name) const
  170. {
  171. return getVarPointer (name) != nullptr;
  172. }
  173. bool NamedValueSet::remove (const Identifier& name)
  174. {
  175. LinkedListPointer<NamedValue>* i = &values;
  176. for (;;)
  177. {
  178. NamedValue* const v = i->get();
  179. if (v == nullptr)
  180. break;
  181. if (v->name == name)
  182. {
  183. delete i->removeNext();
  184. return true;
  185. }
  186. i = &(v->nextListItem);
  187. }
  188. return false;
  189. }
  190. const Identifier NamedValueSet::getName (const int index) const
  191. {
  192. const NamedValue* const v = values[index];
  193. jassert (v != nullptr);
  194. return v->name;
  195. }
  196. const var& NamedValueSet::getValueAt (const int index) const
  197. {
  198. const NamedValue* const v = values[index];
  199. jassert (v != nullptr);
  200. return v->value;
  201. }
  202. void NamedValueSet::setFromXmlAttributes (const XmlElement& xml)
  203. {
  204. clear();
  205. LinkedListPointer<NamedValue>::Appender appender (values);
  206. const int numAtts = xml.getNumAttributes(); // xxx inefficient - should write an att iterator..
  207. for (int i = 0; i < numAtts; ++i)
  208. appender.append (new NamedValue (xml.getAttributeName (i), var (xml.getAttributeValue (i))));
  209. }
  210. void NamedValueSet::copyToXmlAttributes (XmlElement& xml) const
  211. {
  212. for (NamedValue* i = values; i != nullptr; i = i->nextListItem)
  213. {
  214. jassert (! i->value.isObject()); // DynamicObjects can't be stored as XML!
  215. xml.setAttribute (i->name.toString(),
  216. i->value.toString());
  217. }
  218. }