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.

ports.h 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /*
  2. * Copyright (c) 2012 Mark McCurry
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  19. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. */
  24. #ifndef RTOSC_PORTS
  25. #define RTOSC_PORTS
  26. #include <vector>
  27. #include <functional>
  28. #include <initializer_list>
  29. #include "rtosc.h"
  30. #include <cstring>
  31. #include <cctype>
  32. #include <cstdlib>
  33. #include <cstdio>
  34. #include <string>
  35. namespace rtosc {
  36. //First define all types
  37. typedef const char *msg_t;
  38. struct Port;
  39. struct Ports;
  40. struct RtData
  41. {
  42. RtData(void);
  43. char *loc;
  44. size_t loc_size;
  45. void *obj;
  46. int matches;
  47. const Port *port;
  48. virtual void reply(const char *path, const char *args, ...);
  49. virtual void reply(const char *msg);
  50. virtual void broadcast(const char *path, const char *args, ...);
  51. virtual void broadcast(const char *msg);
  52. };
  53. /**
  54. * Port in rtosc dispatching hierarchy
  55. */
  56. struct Port {
  57. const char *name; //< Pattern for messages to match
  58. const char *metadata;//< Statically accessable data about port
  59. const Ports *ports; //< Pointer to further ports
  60. std::function<void(msg_t, RtData&)> cb;//< Callback for matching functions
  61. class MetaIterator
  62. {
  63. public:
  64. MetaIterator(const char *str);
  65. //A bit odd to return yourself, but it seems to work for this
  66. //context
  67. const MetaIterator& operator*(void) const {return *this;}
  68. const MetaIterator* operator->(void) const {return this;}
  69. bool operator==(MetaIterator a) {return title == a.title;}
  70. bool operator!=(MetaIterator a) {return title != a.title;}
  71. MetaIterator& operator++(void);
  72. const char *title;
  73. const char *value;
  74. };
  75. class MetaContainer
  76. {
  77. public:
  78. MetaContainer(const char *str_);
  79. MetaIterator begin(void) const;
  80. MetaIterator end(void) const;
  81. MetaIterator find(const char *str) const;
  82. size_t length(void) const;
  83. const char *operator[](const char *str) const;
  84. const char *str_ptr;
  85. };
  86. MetaContainer meta(void) const
  87. {
  88. if(metadata && *metadata == ':')
  89. return MetaContainer(metadata+1);
  90. else
  91. return MetaContainer(metadata);
  92. }
  93. };
  94. /**
  95. * Ports - a dispatchable collection of Port entries
  96. *
  97. * This structure makes it somewhat easier to perform actions on collections of
  98. * port entries and it is responsible for the dispatching of OSC messages to
  99. * their respective ports.
  100. * That said, it is a very simple structure, which uses a stl container to store
  101. * all data in a simple dispatch table.
  102. * All methods post-initialization are RT safe (assuming callbacks are RT safe)
  103. */
  104. struct Ports
  105. {
  106. std::vector<Port> ports;
  107. typedef std::vector<Port>::const_iterator itr_t;
  108. /**Forwards to builtin container*/
  109. itr_t begin() const {return ports.begin();}
  110. /**Forwards to builtin container*/
  111. itr_t end() const {return ports.end();}
  112. /**Forwards to builtin container*/
  113. size_t size() const {return ports.size();}
  114. /**Forwards to builtin container*/
  115. const Port &operator[](unsigned i) const {return ports[i];}
  116. Ports(std::initializer_list<Port> l);
  117. ~Ports(void);
  118. Ports(const Ports&) = delete;
  119. /**
  120. * Dispatches message to all matching ports.
  121. * This uses simple pattern matching available in rtosc::match.
  122. *
  123. * @param m a valid OSC message
  124. * @param d The RtData object shall contain a path buffer (or null), the length of
  125. * the buffer, a pointer to data.
  126. */
  127. void dispatch(const char *m, RtData &d) const;
  128. /**
  129. * Retrieve local port by name
  130. * TODO implement full matching
  131. */
  132. const Port *operator[](const char *name) const;
  133. /**
  134. * Find the best match for a given path
  135. *
  136. * @parameter path partial OSC path
  137. * @returns first path prefixed by the argument
  138. *
  139. * Example usage:
  140. * @code
  141. * Ports p = {{"foo",0,0,dummy_method},
  142. * {"flam",0,0,dummy_method},
  143. * {"bar",0,0,dummy_method}};
  144. * p.apropos("/b")->name;//bar
  145. * p.apropos("/f")->name;//foo
  146. * p.apropos("/fl")->name;//flam
  147. * p.apropos("/gg");//NULL
  148. * @endcode
  149. */
  150. const Port *apropos(const char *path) const;
  151. private:
  152. //Performance hacks
  153. class Port_Matcher *impl;
  154. unsigned elms;
  155. };
  156. /*********************
  157. * Port walking code *
  158. *********************/
  159. //typedef std::function<void(const Port*,const char*)> port_walker_t;
  160. typedef void(*port_walker_t)(const Port*,const char*,void*);
  161. void walk_ports(const Ports *base,
  162. char *name_buffer,
  163. size_t buffer_size,
  164. void *data,
  165. port_walker_t walker);
  166. /*********************
  167. * Port Dumping code *
  168. *********************/
  169. struct OscDocFormatter
  170. {
  171. const Ports *p;
  172. std::string prog_name;
  173. std::string uri;
  174. std::string doc_origin;
  175. std::string author_first;
  176. std::string author_last;
  177. //TODO extend this some more
  178. };
  179. std::ostream &operator<<(std::ostream &o, OscDocFormatter &formatter);
  180. };
  181. #endif