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.

240 lines
7.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  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 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. OSCBundle::OSCBundle()
  20. {
  21. }
  22. OSCBundle::OSCBundle (OSCTimeTag t) : timeTag (t)
  23. {
  24. }
  25. // Note: The class invariant of OSCBundle::Element is that
  26. // at least one of the pointers bundle and message is nullptr
  27. // and the other one always points to a valid object.
  28. OSCBundle::Element::Element (OSCMessage m)
  29. : message (new OSCMessage (m)), bundle (nullptr)
  30. {
  31. }
  32. OSCBundle::Element::Element (OSCBundle b)
  33. : message (nullptr), bundle (new OSCBundle (b))
  34. {
  35. }
  36. //==============================================================================
  37. OSCBundle::Element::Element (const Element& other)
  38. {
  39. if (this != &other)
  40. {
  41. message = nullptr;
  42. bundle = nullptr;
  43. if (other.isMessage())
  44. message = new OSCMessage (other.getMessage());
  45. else
  46. bundle = new OSCBundle (other.getBundle());
  47. }
  48. }
  49. //==============================================================================
  50. OSCBundle::Element::~Element()
  51. {
  52. bundle = nullptr;
  53. message = nullptr;
  54. }
  55. //==============================================================================
  56. bool OSCBundle::Element::isMessage() const noexcept
  57. {
  58. return message != nullptr;
  59. }
  60. bool OSCBundle::Element::isBundle() const noexcept
  61. {
  62. return bundle != nullptr;
  63. }
  64. //==============================================================================
  65. const OSCMessage& OSCBundle::Element::getMessage() const
  66. {
  67. if (message == nullptr)
  68. {
  69. // This element is not a bundle! You must check this first before accessing.
  70. jassertfalse;
  71. throw OSCInternalError ("Access error in OSC bundle element.");
  72. }
  73. return *message;
  74. }
  75. //==============================================================================
  76. const OSCBundle& OSCBundle::Element::getBundle() const
  77. {
  78. if (bundle == nullptr)
  79. {
  80. // This element is not a bundle! You must check this first before accessing.
  81. jassertfalse;
  82. throw OSCInternalError ("Access error in OSC bundle element.");
  83. }
  84. return *bundle;
  85. }
  86. //==============================================================================
  87. #if JUCE_UNIT_TESTS
  88. class OSCBundleTests : public UnitTest
  89. {
  90. public:
  91. OSCBundleTests() : UnitTest ("OSCBundle class") {}
  92. void runTest()
  93. {
  94. beginTest ("Construction");
  95. {
  96. OSCBundle bundle;
  97. expect (bundle.getTimeTag().isImmediately());
  98. }
  99. beginTest ("Construction with time tag");
  100. {
  101. Time in100Seconds = (Time (Time::currentTimeMillis()) + RelativeTime (100.0));
  102. OSCBundle bundle (in100Seconds);
  103. expect (! bundle.getTimeTag().isImmediately());
  104. expect (bundle.getTimeTag().toTime() == in100Seconds);
  105. }
  106. beginTest ("Usage when containing messages");
  107. {
  108. OSCBundle testBundle = generateTestBundle();
  109. expectBundleEqualsTestBundle (testBundle);
  110. }
  111. beginTest ("Usage when containing other bundles (recursively)");
  112. {
  113. OSCBundle complexTestBundle;
  114. complexTestBundle.addElement (generateTestBundle());
  115. complexTestBundle.addElement (OSCMessage ("/test/"));
  116. complexTestBundle.addElement (generateTestBundle());
  117. expect (complexTestBundle.size() == 3);
  118. OSCBundle::Element* elements = complexTestBundle.begin();
  119. expect (! elements[0].isMessage());
  120. expect (elements[0].isBundle());
  121. expect (elements[1].isMessage());
  122. expect (! elements[1].isBundle());
  123. expect (! elements[2].isMessage());
  124. expect (elements[2].isBundle());
  125. expectBundleEqualsTestBundle (elements[0].getBundle());
  126. expect (elements[1].getMessage().size() == 0);
  127. expect (elements[1].getMessage().getAddressPattern().toString() == "/test");
  128. expectBundleEqualsTestBundle (elements[2].getBundle());
  129. }
  130. }
  131. private:
  132. int testInt = 127;
  133. float testFloat = 1.5;
  134. OSCBundle generateTestBundle()
  135. {
  136. OSCBundle bundle;
  137. OSCMessage msg1 ("/test/fader");
  138. msg1.addInt32 (testInt);
  139. OSCMessage msg2 ("/test/foo");
  140. msg2.addString ("bar");
  141. msg2.addFloat32 (testFloat);
  142. bundle.addElement (msg1);
  143. bundle.addElement (msg2);
  144. return bundle;
  145. }
  146. void expectBundleEqualsTestBundle (const OSCBundle& bundle)
  147. {
  148. expect (bundle.size() == 2);
  149. expect (bundle[0].isMessage());
  150. expect (! bundle[0].isBundle());
  151. expect (bundle[1].isMessage());
  152. expect (! bundle[1].isBundle());
  153. int numElementsCounted = 0;
  154. for (OSCBundle::Element* element = bundle.begin(); element != bundle.end(); ++element)
  155. {
  156. expect (element->isMessage());
  157. expect (! element->isBundle());
  158. ++numElementsCounted;
  159. }
  160. expectEquals (numElementsCounted, 2);
  161. OSCBundle::Element* e = bundle.begin();
  162. expect (e[0].getMessage().size() == 1);
  163. expect (e[0].getMessage().begin()->getInt32() == testInt);
  164. expect (e[1].getMessage().size() == 2);
  165. expect (e[1].getMessage()[1].getFloat32() == testFloat);
  166. }
  167. };
  168. static OSCBundleTests OSCBundleUnitTests;
  169. //==============================================================================
  170. class OSCBundleElementTests : public UnitTest
  171. {
  172. public:
  173. OSCBundleElementTests() : UnitTest ("OSCBundle::Element class") {}
  174. void runTest()
  175. {
  176. beginTest ("Construction from OSCMessage");
  177. {
  178. float testFloat = -0.125;
  179. OSCMessage msg ("/test");
  180. msg.addFloat32 (testFloat);
  181. OSCBundle::Element element (msg);
  182. expect (element.isMessage());
  183. expect (element.getMessage().size() == 1);
  184. expect (element.getMessage()[0].getType() == OSCTypes::float32);
  185. expect (element.getMessage()[0].getFloat32() == testFloat);
  186. }
  187. }
  188. };
  189. static OSCBundleElementTests OSCBundleElementUnitTests;
  190. #endif // JUCE_UNIT_TESTS