OSSIA
Open Scenario System for Interactive Application
ossia-max.hpp
1 #pragma once
2 #define OSSIA_MAX_AUTOREGISTER 1
3 #include "ext.h"
4 #include "ext_obex.h"
5 #include "jpatcher_api.h"
6 
7 #include <ossia/detail/config.hpp>
8 #undef error
9 #undef post
10 
11 #include "ZeroconfMinuitListener.hpp"
12 #include "ZeroconfOscqueryListener.hpp"
13 #include "assert.hpp"
14 #include "attribute.hpp"
15 #include "client.hpp"
16 #include "cue.hpp"
17 #include "device.hpp"
18 #include "explorer.hpp"
19 #include "fuzzysearch.hpp"
20 #include "logger.hpp"
21 #include "model.hpp"
22 #include "monitor.hpp"
23 #include "ossia_object.hpp"
24 #include "parameter.hpp"
25 #include "remote.hpp"
26 #include "router.hpp"
27 #include "search.hpp"
28 #include "view.hpp"
29 
30 #include <ossia/detail/hash_map.hpp>
31 #include <ossia/detail/safe_vec.hpp>
32 #include <ossia/network/common/websocket_log_sink.hpp>
33 
34 #include <ossia-max/src/object_base.hpp>
35 
36 #include <ossia-max_export.h>
37 
38 extern "C" {
39 OSSIA_MAX_EXPORT void ossia_router_setup();
40 OSSIA_MAX_EXPORT void ossia_attribute_setup();
41 OSSIA_MAX_EXPORT void ossia_client_setup();
42 OSSIA_MAX_EXPORT void ossia_device_setup();
43 OSSIA_MAX_EXPORT void ossia_logger_setup();
44 OSSIA_MAX_EXPORT void ossia_model_setup();
45 OSSIA_MAX_EXPORT void ossia_parameter_setup();
46 OSSIA_MAX_EXPORT void ossia_remote_setup();
47 OSSIA_MAX_EXPORT void ossia_view_setup();
48 OSSIA_MAX_EXPORT void ossia_ossia_setup();
49 OSSIA_MAX_EXPORT void ossia_explorer_setup();
50 OSSIA_MAX_EXPORT void ossia_search_setup();
51 OSSIA_MAX_EXPORT void ossia_monitor_setup();
52 OSSIA_MAX_EXPORT void ossia_fuzzysearch_setup();
53 OSSIA_MAX_EXPORT void ossia_assert_setup();
54 OSSIA_MAX_EXPORT void ossia_cue_setup();
55 OSSIA_MAX_EXPORT void ossia_equals_setup();
56 }
57 
58 namespace ossia
59 {
60 namespace max_binding
61 {
62 
63 #pragma mark -
64 #pragma mark Library
65 
66 struct max_msp_log_sink final : public spdlog::sinks::sink
67 {
68  void log(const spdlog::details::log_msg& msg) override
69  {
70  std::string s(msg.payload.data(), msg.payload.size());
71  switch(msg.level)
72  {
73  case spdlog::level::warn:
74  case spdlog::level::err: {
75  error("%s", s.c_str());
76  break;
77  }
78 
79  default:
80  post("%s", s.c_str());
81  break;
82  }
83  }
84 
85  void flush() override { }
86 
87  void set_pattern(const std::string& pattern) override { }
88  void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) override { }
89 };
90 
91 struct patcher_descriptor
92 {
93  ossia::safe_set<parameter*> parameters{};
94  ossia::safe_set<remote*> remotes{};
95  ossia::safe_set<attribute*> attributes{};
96  ossia::safe_set<ocue*> cues{};
97  model* model{};
98  view* view{};
99  device* device{};
100  client* client{};
101 
102  t_object* parent_patcher{};
103  ossia::safe_set<t_object*> subpatchers{};
104 
105  bool loadbanged{}; // true if patcher have been loadbanged already
106 
107  long poly_index{
108  -1}; // 0 when not in a poly~, instance index otherwise, -1 uninitialized
109 
110  bool empty() const
111  {
112  return parameters.empty() && remotes.empty() && attributes.empty() && cues.empty()
113  && model != nullptr && view != nullptr && device != nullptr
114  && client != nullptr;
115  }
116 
117  auto size() const
118  {
119  return parameters.size() + remotes.size() + attributes.size() + cues.size()
120  + (model ? 1 : 0) + (view ? 1 : 0) + (device ? 1 : 0) + (client ? 1 : 0);
121  }
122 
123  bool has_no_master_node()
124  {
125  return model == nullptr && view == nullptr && device == nullptr && client == nullptr;
126  }
127 };
128 
129 struct configuration
130 {
131  bool defer_by_default = true;
132  bool autoregister = true;
133 };
134 
135 class ossia_max
136 {
137 public:
138  static ossia_max& instance();
139  static const std::shared_ptr<ossia::net::generic_device>& get_default_device()
140  {
141  return instance().m_device;
142  }
143 
144  // static void register_nodes(ossia_max* x);
145  static void discover_network_devices(ossia_max* x);
146 
147  template <typename T>
148  t_class* get_class()
149  {
150  if(std::is_same<T, parameter>::value)
151  return ossia_parameter_class;
152  if(std::is_same<T, remote>::value)
153  return ossia_remote_class;
154  if(std::is_same<T, model>::value)
155  return ossia_model_class;
156  if(std::is_same<T, view>::value)
157  return ossia_view_class;
158  if(std::is_same<T, device>::value)
159  return ossia_device_class;
160  if(std::is_same<T, client>::value)
161  return ossia_client_class;
162  if(std::is_same<T, attribute>::value)
163  return ossia_attribute_class;
164  if(std::is_same<T, ossia_object>::value)
165  return ossia_ossia_class;
166  if(std::is_same<T, ossia::max_binding::logger>::value)
167  return ossia_logger_class;
168  if(std::is_same<T, ossia::max_binding::explorer>::value)
169  return ossia_explorer_class;
170  if(std::is_same<T, ossia::max_binding::monitor>::value)
171  return ossia_monitor_class;
172  if(std::is_same<T, ossia::max_binding::search>::value)
173  return ossia_search_class;
174  if(std::is_same<T, ossia::max_binding::router>::value)
175  return ossia_router_class;
176  if(std::is_same<T, ossia::max_binding::fuzzysearch>::value)
177  return ossia_fuzzysearch_class;
178  if(std::is_same<T, ossia::max_binding::oassert>::value)
179  return ossia_assert_class;
180  if(std::is_same<T, ossia::max_binding::ocue>::value)
181  return ossia_cue_class;
182  return nullptr;
183  }
184 
185  void set_log_level(t_symbol* log_sym)
186  {
187  std::vector<spdlog::string_view_t> vec SPDLOG_LEVEL_NAMES;
188  auto it = std::find(vec.begin(), vec.end(), log_sym->s_name);
189  if(it != vec.end())
190  {
191  int level = it - vec.begin();
192  m_log_sink.get()->set_level(static_cast<spdlog::level::level_enum>(level));
193  }
194  else
195  {
196  error("Unknown log level : %s", log_sym->s_name);
197  }
198  }
199 
200  t_class* ossia_router_class{};
201  t_class* ossia_client_class{};
202  t_class* ossia_attribute_class{};
203  t_class* ossia_device_class{};
204  t_class* ossia_explorer_class{};
205  t_class* ossia_monitor_class{};
206  t_class* ossia_search_class{};
207  t_class* ossia_fuzzysearch_class{};
208  t_class* ossia_logger_class{};
209  t_class* ossia_model_class{};
210  t_class* ossia_parameter_class{};
211  t_class* ossia_remote_class{};
212  t_class* ossia_view_class{};
213  t_class* ossia_ossia_class{};
214  t_class* ossia_assert_class{};
215  t_class* ossia_cue_class{};
216  t_class* ossia_equals_class{};
217  static t_class* ossia_patcher_listener_class;
218 
219  // keep list of all objects
220  // TODO is it still needed ?
221  ossia::safe_vector<remote*> remotes;
222  ossia::safe_vector<view*> views;
223  ossia::safe_vector<device*> devices;
224  ossia::safe_vector<client*> clients;
225  ossia::safe_vector<logger*> loggers;
226 
227  static ossia::hash_map<ossia::net::node_base*, ossia::safe_set<matcher*>>
228  s_node_matchers_map;
229  static std::recursive_mutex s_node_matchers_mut;
230 
231  // TODO is this still needed ?
232  bool registering_nodes = false;
233 
234  std::map<t_object*, patcher_descriptor> patchers;
235 
236  static patcher_descriptor& get_patcher_descriptor(t_object* patcher);
237  static void remove_patcher_descriptor(t_object* patcher);
238 
239  void* m_reg_clock{};
240  static void* s_browse_clock;
241 
242  static ZeroconfOscqueryListener s_zeroconf_oscq_listener;
243  static ZeroconfMinuitListener s_zeroconf_minuit_listener;
244 
245  configuration config;
246 
247 private:
248  ossia_max();
249  ~ossia_max();
250  ossia_max(const ossia_max&) = delete;
251  ossia_max(ossia_max&&) = delete;
252 
253  ossia::net::local_protocol* m_localProtocol{};
254  std::shared_ptr<ossia::net::generic_device> m_device;
255  string_map<std::shared_ptr<ossia::websocket_threaded_connection>> m_connections;
256  std::shared_ptr<max_msp_log_sink> m_log_sink;
257 
258  t_object* m_patcher_listener;
259 };
260 
261 template <typename T, typename... Args>
262 T* make_ossia(Args&&... args)
263 {
264  auto obj = object_alloc(ossia_max::instance().get_class<T>());
265  if(obj)
266  {
267  t_object tmp;
268  memcpy(&tmp, obj, sizeof(t_object));
269  auto x = new(obj) T{std::forward<Args>(args)...};
270  memcpy(x, &tmp, sizeof(t_object));
271 
272  return x;
273  }
274  return nullptr;
275 }
276 
277 } // max namespace
278 } // ossia namespace
A protocol used to expose a local application's data through multiple other protocols.
Definition: local.hpp:22
Definition: git_info.h:7