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.

238 lines
7.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. OSCBundle::OSCBundle()
  18. {
  19. }
  20. OSCBundle::OSCBundle (OSCTimeTag t) : timeTag (t)
  21. {
  22. }
  23. // Note: The class invariant of OSCBundle::Element is that
  24. // at least one of the pointers bundle and message is nullptr
  25. // and the other one always points to a valid object.
  26. OSCBundle::Element::Element (OSCMessage m)
  27. : message (new OSCMessage (m)), bundle (nullptr)
  28. {
  29. }
  30. OSCBundle::Element::Element (OSCBundle b)
  31. : message (nullptr), bundle (new OSCBundle (b))
  32. {
  33. }
  34. //==============================================================================
  35. OSCBundle::Element::Element (const Element& other)
  36. {
  37. if (this != &other)
  38. {
  39. message = nullptr;
  40. bundle = nullptr;
  41. if (other.isMessage())
  42. message = new OSCMessage (other.getMessage());
  43. else
  44. bundle = new OSCBundle (other.getBundle());
  45. }
  46. }
  47. //==============================================================================
  48. OSCBundle::Element::~Element()
  49. {
  50. bundle = nullptr;
  51. message = nullptr;
  52. }
  53. //==============================================================================
  54. bool OSCBundle::Element::isMessage() const noexcept
  55. {
  56. return message != nullptr;
  57. }
  58. bool OSCBundle::Element::isBundle() const noexcept
  59. {
  60. return bundle != nullptr;
  61. }
  62. //==============================================================================
  63. const OSCMessage& OSCBundle::Element::getMessage() const
  64. {
  65. if (message == nullptr)
  66. {
  67. // This element is not a bundle! You must check this first before accessing.
  68. jassertfalse;
  69. throw OSCInternalError ("Access error in OSC bundle element.");
  70. }
  71. return *message;
  72. }
  73. //==============================================================================
  74. const OSCBundle& OSCBundle::Element::getBundle() const
  75. {
  76. if (bundle == nullptr)
  77. {
  78. // This element is not a bundle! You must check this first before accessing.
  79. jassertfalse;
  80. throw OSCInternalError ("Access error in OSC bundle element.");
  81. }
  82. return *bundle;
  83. }
  84. //==============================================================================
  85. #if JUCE_UNIT_TESTS
  86. class OSCBundleTests : public UnitTest
  87. {
  88. public:
  89. OSCBundleTests() : UnitTest ("OSCBundle class") {}
  90. void runTest()
  91. {
  92. beginTest ("Construction");
  93. {
  94. OSCBundle bundle;
  95. expect (bundle.getTimeTag().isImmediately());
  96. }
  97. beginTest ("Construction with time tag");
  98. {
  99. Time in100Seconds = (Time (Time::currentTimeMillis()) + RelativeTime (100.0));
  100. OSCBundle bundle (in100Seconds);
  101. expect (! bundle.getTimeTag().isImmediately());
  102. expect (bundle.getTimeTag().toTime() == in100Seconds);
  103. }
  104. beginTest ("Usage when containing messages");
  105. {
  106. OSCBundle testBundle = generateTestBundle();
  107. expectBundleEqualsTestBundle (testBundle);
  108. }
  109. beginTest ("Usage when containing other bundles (recursively)");
  110. {
  111. OSCBundle complexTestBundle;
  112. complexTestBundle.addElement (generateTestBundle());
  113. complexTestBundle.addElement (OSCMessage ("/test/"));
  114. complexTestBundle.addElement (generateTestBundle());
  115. expect (complexTestBundle.size() == 3);
  116. OSCBundle::Element* elements = complexTestBundle.begin();
  117. expect (! elements[0].isMessage());
  118. expect (elements[0].isBundle());
  119. expect (elements[1].isMessage());
  120. expect (! elements[1].isBundle());
  121. expect (! elements[2].isMessage());
  122. expect (elements[2].isBundle());
  123. expectBundleEqualsTestBundle (elements[0].getBundle());
  124. expect (elements[1].getMessage().size() == 0);
  125. expect (elements[1].getMessage().getAddressPattern().toString() == "/test");
  126. expectBundleEqualsTestBundle (elements[2].getBundle());
  127. }
  128. }
  129. private:
  130. int testInt = 127;
  131. float testFloat = 1.5;
  132. OSCBundle generateTestBundle()
  133. {
  134. OSCBundle bundle;
  135. OSCMessage msg1 ("/test/fader");
  136. msg1.addInt32 (testInt);
  137. OSCMessage msg2 ("/test/foo");
  138. msg2.addString ("bar");
  139. msg2.addFloat32 (testFloat);
  140. bundle.addElement (msg1);
  141. bundle.addElement (msg2);
  142. return bundle;
  143. }
  144. void expectBundleEqualsTestBundle (const OSCBundle& bundle)
  145. {
  146. expect (bundle.size() == 2);
  147. expect (bundle[0].isMessage());
  148. expect (! bundle[0].isBundle());
  149. expect (bundle[1].isMessage());
  150. expect (! bundle[1].isBundle());
  151. int numElementsCounted = 0;
  152. for (OSCBundle::Element* element = bundle.begin(); element != bundle.end(); ++element)
  153. {
  154. expect (element->isMessage());
  155. expect (! element->isBundle());
  156. ++numElementsCounted;
  157. }
  158. expectEquals (numElementsCounted, 2);
  159. OSCBundle::Element* e = bundle.begin();
  160. expect (e[0].getMessage().size() == 1);
  161. expect (e[0].getMessage().begin()->getInt32() == testInt);
  162. expect (e[1].getMessage().size() == 2);
  163. expect (e[1].getMessage()[1].getFloat32() == testFloat);
  164. }
  165. };
  166. static OSCBundleTests OSCBundleUnitTests;
  167. //==============================================================================
  168. class OSCBundleElementTests : public UnitTest
  169. {
  170. public:
  171. OSCBundleElementTests() : UnitTest ("OSCBundle::Element class") {}
  172. void runTest()
  173. {
  174. beginTest ("Construction from OSCMessage");
  175. {
  176. float testFloat = -0.125;
  177. OSCMessage msg ("/test");
  178. msg.addFloat32 (testFloat);
  179. OSCBundle::Element element (msg);
  180. expect (element.isMessage());
  181. expect (element.getMessage().size() == 1);
  182. expect (element.getMessage()[0].getType() == OSCTypes::float32);
  183. expect (element.getMessage()[0].getFloat32() == testFloat);
  184. }
  185. }
  186. };
  187. static OSCBundleElementTests OSCBundleElementUnitTests;
  188. #endif // JUCE_UNIT_TESTS