OSSIA
Open Scenario System for Interactive Application
phidgets_parameter.hpp
1 #pragma once
3 #include <ossia/network/generic/generic_node.hpp>
4 #include <ossia/network/generic/generic_parameter.hpp>
5 #include <ossia/network/phidgets/phidgets_node.hpp>
6 namespace ossia
7 {
8 
9 template <typename Impl>
10 class phidget_generic_parameter : public ossia::net::parameter_base
11 {
12  PhidgetHandle m_phidget{};
13  ossia::domain m_domain;
14  // ossia::value m_value, m_previousValue;
15  std::mutex m_valueMutex;
16 
17  auto get_phidget() const
18  {
19  return reinterpret_cast<decltype(Impl::phidget)>(m_phidget);
20  }
21  auto get_impl() const { return Impl{get_phidget()}; }
22 
23 public:
24  phidget_generic_parameter(PhidgetHandle p, net::node_base& par)
25  : ossia::net::parameter_base{par}
26  , m_phidget{p}
27  {
28  m_domain = get_impl().get_domain();
29  }
30 
31  void on_first_callback_added() override { get_impl().enable_callbacks(*this); }
32  void on_removing_last_callback() override { get_impl().disable_callbacks(); }
33 
34  ~phidget_generic_parameter() { }
35 
36  void pull_value() override { }
37 
38  ossia::value value() const override { return get_impl().get_value(); }
39 
40  net::parameter_base& push_value(const ossia::value& val) override
41  {
42  set_value(val);
43  return *this;
44  }
45  net::parameter_base& push_value(ossia::value&& val) override
46  {
47  set_value(val);
48  return *this;
49  }
50  net::parameter_base& push_value() override { return *this; }
51 
52  net::parameter_base& set_value(const ossia::value& val) override
53  {
54  if(!val.valid())
55  return *this;
56 
57  get_impl().set_value(ossia::convert<decltype(Impl{get_phidget()}.get_value())>(val));
58  send(val);
59  return *this;
60  }
61 
62  net::parameter_base& set_value(ossia::value&& v) override { return set_value(v); }
63 
64  val_type get_value_type() const override
65  {
66  return ossia::value_trait<decltype(Impl{get_phidget()}.get_value())>::ossia_enum;
67  }
68 
69  net::parameter_base& set_value_type(val_type) override { return *this; }
70 
71  access_mode get_access() const override { return ossia::access_mode::BI; }
72  net::parameter_base& set_access(access_mode) override { return *this; }
73 
74  const domain& get_domain() const override { return m_domain; }
75  net::parameter_base& set_domain(const domain&) override { return *this; }
76 
77  bounding_mode get_bounding() const override { return ossia::bounding_mode::FREE; }
78  net::parameter_base& set_bounding(bounding_mode) override { return *this; }
79 };
80 
81 template <typename Impl>
82 class phidget_control_parameter : public ossia::net::parameter_base
83 {
84  auto get_phidget() const
85  {
86  return reinterpret_cast<decltype(Impl::phidget)>(m_phidget);
87  }
88  auto get_impl() const { return Impl{get_phidget()}; }
89 
90  PhidgetHandle m_phidget{};
91  ossia::domain m_domain;
92 
93  using value_type = decltype(std::declval<Impl>().get_value());
94  value_type m_value{};
95 
96 public:
97  phidget_control_parameter(PhidgetHandle p, net::node_base& par)
98  : ossia::net::parameter_base{par}
99  , m_phidget{p}
100  {
101  m_domain = get_impl().get_domain();
102  }
103 
104  ~phidget_control_parameter() override { }
105 
106  ossia::value value() const override { return m_value; }
107 
108  void pull_value() override { }
109  net::parameter_base& push_value(const ossia::value& val) override
110  {
111  set_value(val);
112  return *this;
113  }
114  net::parameter_base& push_value(ossia::value&& val) override
115  {
116  set_value(val);
117  return *this;
118  }
119  net::parameter_base& push_value() override
120  {
121  set_value(value());
122  return *this;
123  }
124 
125  net::parameter_base& set_value(const ossia::value& val) override
126  {
127  if(!val.valid())
128  return *this;
129 
130  auto v = ossia::convert<value_type>(val);
131  m_value = v;
132  get_impl().set_value(v);
133  send(val);
134  return *this;
135  }
136 
137  net::parameter_base& set_value(ossia::value&& v) override { return set_value(v); }
138 
139  val_type get_value_type() const override
140  {
141  return ossia::value_trait<decltype(Impl{get_phidget()}.get_value())>::ossia_enum;
142  }
143 
144  net::parameter_base& set_value_type(val_type) override { return *this; }
145 
146  access_mode get_access() const override { return ossia::access_mode::BI; }
147  net::parameter_base& set_access(access_mode) override { return *this; }
148 
149  const domain& get_domain() const override { return m_domain; }
150  net::parameter_base& set_domain(const domain&) override { return *this; }
151 
152  bounding_mode get_bounding() const override { return ossia::bounding_mode::FREE; }
153  net::parameter_base& set_bounding(bounding_mode) override { return *this; }
154 };
155 
156 class phidget_open_parameter : public ossia::net::parameter_base
157 {
158  PhidgetHandle m_phidget{};
159  bool m_open{false};
160 
161 public:
162  phidget_open_parameter(PhidgetHandle p, net::node_base& par)
163  : ossia::net::parameter_base{par}
164  , m_phidget{p}
165  {
166  }
167 
168  ~phidget_open_parameter() override { Phidget_close(m_phidget); }
169 
170  ossia::value value() const override { return m_open; }
171 
172  void pull_value() override { }
173 
174  net::parameter_base& push_value(const ossia::value& val) override
175  {
176  set_value(val);
177  return *this;
178  }
179  net::parameter_base& push_value(ossia::value&& val) override
180  {
181  set_value(val);
182  return *this;
183  }
184  net::parameter_base& push_value() override { return *this; }
185 
186  net::parameter_base& set_value(const ossia::value& val) override
187  {
188  if(!val.valid())
189  return *this;
190 
191  auto res = ossia::convert<bool>(val);
192  if(res != value())
193  {
194  if(res)
195  {
196  auto err = Phidget_openWaitForAttachment(m_phidget, 1000);
197  if(err != EPHIDGET_OK)
198  {
199  const char* err_txt{};
200  Phidget_getErrorDescription(err, &err_txt);
201  if(err_txt)
202  ossia::logger().error(
203  "Phidget Open error: {} ({})", this->get_node().osc_address(), err_txt);
204  else
205  ossia::logger().error(
206  "Phidget Open error: {} (timeout)", this->get_node().osc_address());
207 
208  res = false;
209  }
210  }
211  else
212  {
213  Phidget_close(m_phidget);
214  }
215  m_open = res;
216  send(res);
217  }
218  return *this;
219  }
220 
221  net::parameter_base& set_value(ossia::value&& v) override { return set_value(v); }
222 
223  val_type get_value_type() const override { return ossia::val_type::BOOL; }
224  net::parameter_base& set_value_type(val_type) override { return *this; }
225 
226  access_mode get_access() const override { return ossia::access_mode::BI; }
227  net::parameter_base& set_access(access_mode) override { return *this; }
228 
229  const domain& get_domain() const override
230  {
231  static const domain d = ossia::make_domain(false, true);
232  return d;
233  }
234  net::parameter_base& set_domain(const domain&) override { return *this; }
235 
236  bounding_mode get_bounding() const override { return ossia::bounding_mode::CLIP; }
237  net::parameter_base& set_bounding(bounding_mode) override { return *this; }
238 };
239 
240 class phidget_channel_parameter : public ossia::net::parameter_base
241 {
242  PhidgetHandle m_phidget{};
243 
244 public:
245  phidget_channel_parameter(PhidgetHandle p, net::node_base& par)
246  : ossia::net::parameter_base{par}
247  , m_phidget{p}
248  {
249  }
250 
251  ~phidget_channel_parameter() override { }
252 
253  ossia::value value() const override
254  {
255  int c{};
256  Phidget_getChannel(m_phidget, &c);
257  return c;
258  }
259 
260  void pull_value() override { }
261 
262  net::parameter_base& push_value(const ossia::value& val) override { return *this; }
263  net::parameter_base& push_value(ossia::value&& val) override { return *this; }
264  net::parameter_base& push_value() override { return *this; }
265  net::parameter_base& set_value(const ossia::value& val) override { return *this; }
266  net::parameter_base& set_value(ossia::value&& v) override { return *this; }
267 
268  val_type get_value_type() const override { return ossia::val_type::INT; }
269  net::parameter_base& set_value_type(val_type) override { return *this; }
270 
271  access_mode get_access() const override { return ossia::access_mode::GET; }
272  net::parameter_base& set_access(access_mode) override { return *this; }
273 
274  const domain& get_domain() const override
275  {
276  static const domain d = ossia::make_domain(0, 1024);
277  return d;
278  }
279  net::parameter_base& set_domain(const domain&) override { return *this; }
280 
281  bounding_mode get_bounding() const override { return ossia::bounding_mode::CLIP; }
282  net::parameter_base& set_bounding(bounding_mode) override { return *this; }
283 };
284 
285 template <typename Impl, typename Parent>
286 auto make_parameter(Parent& parent)
287 {
288  return std::make_unique<phidget_generic_parameter<Impl>>(parent.phidget(), parent);
289 }
290 
291 template <typename Impl>
292 struct Control_Double_parameter
293 {
294  typename Impl::handle_type phidget;
295 
296  float get_value()
297  {
298  double val;
299  if(Impl::Get(phidget, &val) != EPHIDGET_OK)
300  val = 0.;
301  return (float)val;
302  }
303 
304  void set_value(float v) { Impl::Set(phidget, v); }
305 
306  ossia::domain get_domain()
307  {
308  double min, max;
309  if(Impl::Min(phidget, &min) != EPHIDGET_OK)
310  min = 0.;
311  if(Impl::Max(phidget, &max) != EPHIDGET_OK)
312  max = 0.;
313  return ossia::make_domain(min, max);
314  }
315 
316  void enable_callbacks(phidget_generic_parameter<Control_Double_parameter>& p) { }
317 
318  void disable_callbacks() { }
319 };
320 
321 template <typename Impl>
322 struct Control_UInt_parameter
323 {
324  typename Impl::handle_type phidget;
325 
326  int get_value()
327  {
328  uint32_t val;
329  if(Impl::Get(phidget, &val) != EPHIDGET_OK)
330  val = 0;
331  return (int)val;
332  }
333 
334  void set_value(int v) { Impl::Set(phidget, v); }
335 
336  ossia::domain get_domain()
337  {
338  uint32_t min, max;
339  if(Impl::Min(phidget, &min) != EPHIDGET_OK)
340  min = 0;
341  if(Impl::Max(phidget, &max) != EPHIDGET_OK)
342  max = 0;
343  return ossia::make_domain((int)min, (int)max);
344  }
345 
346  void enable_callbacks(phidget_generic_parameter<Control_UInt_parameter>& p) { }
347 
348  void disable_callbacks() { }
349 };
350 
351 template <typename Impl>
352 struct Double_parameter
353 {
354  typename Impl::handle_type phidget;
355 
356  float get_value()
357  {
358  double val;
359  if(Impl::Get(phidget, &val) != EPHIDGET_OK)
360  val = 0.;
361  return (float)val;
362  }
363 
364  void set_value(float) { }
365 
366  ossia::domain get_domain()
367  {
368  double min, max;
369  if(Impl::Min(phidget, &min) != EPHIDGET_OK)
370  min = 0.;
371  if(Impl::Max(phidget, &max) != EPHIDGET_OK)
372  max = 0.;
373  return ossia::make_domain(min, max);
374  }
375 
376  void enable_callbacks(phidget_generic_parameter<Double_parameter>& p)
377  {
378  Impl::Change(
379  phidget,
380  [](typename Impl::handle_type ch, void* ctx, const double ratio) {
381  auto& p = *static_cast<phidget_generic_parameter<Double_parameter>*>(ctx);
382  p.set_value(ratio);
383  },
384  &p);
385  }
386 
387  void disable_callbacks() { Impl::Change(phidget, nullptr, nullptr); }
388 };
389 
390 template <typename Impl>
391 struct UInt_parameter
392 {
393  typename Impl::handle_type phidget;
394 
395  int get_value()
396  {
397  uint32_t val;
398  if(Impl::Get(phidget, &val) != EPHIDGET_OK)
399  val = 0;
400  return (int)val;
401  }
402 
403  void set_value(int) { }
404 
405  ossia::domain get_domain()
406  {
407  uint32_t min, max;
408  if(Impl::Min(phidget, &min) != EPHIDGET_OK)
409  min = 0;
410  if(Impl::Max(phidget, &max) != EPHIDGET_OK)
411  max = 0;
412  return ossia::make_domain((int)min, (int)max);
413  }
414 
415  void enable_callbacks(phidget_generic_parameter<UInt_parameter>& p)
416  {
417  Impl::Change(
418  phidget,
419  [](typename Impl::handle_type ch, void* ctx, const uint32_t ratio) {
420  auto& p = *static_cast<phidget_generic_parameter<UInt_parameter>*>(ctx);
421  p.set_value((int)ratio);
422  },
423  &p);
424  }
425 
426  void disable_callbacks() { Impl::Change(phidget, nullptr, nullptr); }
427 };
428 
429 template <typename Impl>
430 struct Vec3_parameter
431 {
432  typename Impl::handle_type phidget;
433 
434  ossia::vec3f get_value()
435  {
436  double val[3]{};
437  if(Impl::Min(phidget, &val) != EPHIDGET_OK)
438  {
439  val[0] = 0;
440  val[1] = 0;
441  val[2] = 0;
442  }
443  return ossia::make_vec(val[0], val[1], val[2]);
444  }
445 
446  void set_value(ossia::vec3f) { }
447 
448  ossia::domain get_domain()
449  {
450  double min[3];
451  double max[3];
452  if(Impl::Min(phidget, &min) != EPHIDGET_OK)
453  {
454  min[0] = 0;
455  min[1] = 0;
456  min[2] = 0;
457  }
458  if(Impl::Max(phidget, &max) != EPHIDGET_OK)
459  {
460  max[0] = 0;
461  max[1] = 0;
462  max[2] = 0;
463  }
464  return ossia::make_domain(
465  ossia::make_vec(min[0], min[1], min[2]),
466  ossia::make_vec(max[0], max[1], max[2]));
467  }
468 
469  void enable_callbacks(phidget_generic_parameter<Vec3_parameter>& p)
470  {
471  Impl::Change(
472  phidget,
473  [](typename Impl::handle_type ch, void* ctx, const double val[3], double ts) {
474  auto& p = *static_cast<phidget_generic_parameter<Vec3_parameter>*>(ctx);
475  p.set_value(ossia::make_vec(val[0], val[1], val[2]));
476  },
477  &p);
478  }
479 
480  void disable_callbacks() { Impl::Change(phidget, nullptr, nullptr); }
481 };
482 
483 class phidget_control_node : public ossia::net::generic_node
484 {
485 public:
486  template <typename Desc>
487  phidget_control_node(
488  Desc desc, std::string name, PhidgetHandle hdl, ossia::net::device_base& dev,
489  ossia::net::node_base& parent)
490  : generic_node{name, dev, parent}
491  {
492  m_parameter = std::make_unique<phidget_control_parameter<Desc>>(hdl, *this);
493  m_device.on_parameter_created(*m_parameter);
494  }
495 };
496 
497 class phidget_open_node : public ossia::net::generic_node
498 {
499 public:
500  phidget_open_node(
501  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
502  : generic_node{"open", dev, parent}
503  {
504  m_parameter = std::make_unique<phidget_open_parameter>(hdl, *this);
505  m_device.on_parameter_created(*m_parameter);
506  }
507 };
508 
509 class phidget_channel_node : public ossia::net::generic_node
510 {
511 public:
512  phidget_channel_node(
513  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
514  : generic_node{"channel", dev, parent}
515  {
516  m_parameter = std::make_unique<phidget_channel_parameter>(hdl, *this);
517  m_device.on_parameter_created(*m_parameter);
518  }
519 };
520 
521 class phidget_voltage_ratio_node : public ossia::phidget_node
522 {
523 public:
524  struct param_desc
525  {
526  using handle_type = PhidgetVoltageRatioInputHandle;
527  inline static const auto Get = PhidgetVoltageRatioInput_getVoltageRatio;
528  inline static const auto Change
529  = PhidgetVoltageRatioInput_setOnVoltageRatioChangeHandler;
530  inline static const auto Min = PhidgetVoltageRatioInput_getMinVoltageRatio;
531  inline static const auto Max = PhidgetVoltageRatioInput_getMaxVoltageRatio;
532  };
533  struct rate_desc
534  {
535  using handle_type = PhidgetVoltageRatioInputHandle;
536  inline static const auto Get = PhidgetVoltageRatioInput_getDataInterval;
537  inline static const auto Set = PhidgetVoltageRatioInput_setDataInterval;
538  inline static const auto Min = PhidgetVoltageRatioInput_getMinDataInterval;
539  inline static const auto Max = PhidgetVoltageRatioInput_getMaxDataInterval;
540  };
541  struct trigger_desc
542  {
543  using handle_type = PhidgetVoltageRatioInputHandle;
544  inline static const auto Get = PhidgetVoltageRatioInput_getVoltageRatioChangeTrigger;
545  inline static const auto Set = PhidgetVoltageRatioInput_setVoltageRatioChangeTrigger;
546  inline static const auto Min
547  = PhidgetVoltageRatioInput_getMinVoltageRatioChangeTrigger;
548  inline static const auto Max
549  = PhidgetVoltageRatioInput_getMaxVoltageRatioChangeTrigger;
550  };
551 
552  phidget_voltage_ratio_node(
553  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
554  : phidget_node{hdl, dev, parent}
555  {
556  }
557 
558  void init()
559  {
560  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
561  m_device.on_parameter_created(*m_parameter);
562 
563  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
564  add_child_simple(
565  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
566  add_child_simple(std::make_unique<ossia::phidget_control_node>(
567  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
568  add_child_simple(std::make_unique<ossia::phidget_control_node>(
569  Control_Double_parameter<trigger_desc>{}, "trigger", m_hdl, m_device, *this));
570  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
571  bool b = ossia::convert<bool>(val);
572  if(b)
573  {
574  m_children[2]->get_parameter()->push_value();
575  m_children[3]->get_parameter()->push_value();
576  }
577  });
578  }
579 };
580 
581 class phidget_current_input_node : public ossia::phidget_node
582 {
583 public:
584  struct param_desc
585  {
586  using handle_type = PhidgetCurrentInputHandle;
587  inline static const auto Get = PhidgetCurrentInput_getCurrent;
588  inline static const auto Change = PhidgetCurrentInput_setOnCurrentChangeHandler;
589  inline static const auto Min = PhidgetCurrentInput_getMinCurrent;
590  inline static const auto Max = PhidgetCurrentInput_getMaxCurrent;
591  };
592 
593  struct rate_desc
594  {
595  using handle_type = PhidgetCurrentInputHandle;
596  inline static const auto Get = PhidgetCurrentInput_getDataInterval;
597  inline static const auto Set = PhidgetCurrentInput_setDataInterval;
598  inline static const auto Min = PhidgetCurrentInput_getMinDataInterval;
599  inline static const auto Max = PhidgetCurrentInput_getMaxDataInterval;
600  };
601 
602  phidget_current_input_node(
603  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
604  : phidget_node{hdl, dev, parent}
605  {
606  }
607 
608  void init()
609  {
610  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
611  m_device.on_parameter_created(*m_parameter);
612  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
613  add_child_simple(
614  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
615  add_child_simple(std::make_unique<ossia::phidget_control_node>(
616  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
617  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
618  bool b = ossia::convert<bool>(val);
619  if(b)
620  {
621  m_children[2]->get_parameter()->push_value();
622  }
623  });
624  }
625 };
626 
627 class phidget_voltage_input_node : public ossia::phidget_node
628 {
629 public:
630  struct param_desc
631  {
632  using handle_type = PhidgetVoltageInputHandle;
633  inline static const auto Get = PhidgetVoltageInput_getVoltage;
634  inline static const auto Change = PhidgetVoltageInput_setOnVoltageChangeHandler;
635  inline static const auto Min = PhidgetVoltageInput_getMinVoltage;
636  inline static const auto Max = PhidgetVoltageInput_getMaxVoltage;
637  };
638 
639  struct rate_desc
640  {
641  using handle_type = PhidgetVoltageInputHandle;
642  inline static const auto Get = PhidgetVoltageInput_getDataInterval;
643  inline static const auto Set = PhidgetVoltageInput_setDataInterval;
644  inline static const auto Min = PhidgetVoltageInput_getMinDataInterval;
645  inline static const auto Max = PhidgetVoltageInput_getMaxDataInterval;
646  };
647  struct trigger_desc
648  {
649  using handle_type = PhidgetVoltageInputHandle;
650  inline static const auto Get = PhidgetVoltageInput_getVoltageChangeTrigger;
651  inline static const auto Set = PhidgetVoltageInput_setVoltageChangeTrigger;
652  inline static const auto Min = PhidgetVoltageInput_getMinVoltageChangeTrigger;
653  inline static const auto Max = PhidgetVoltageInput_getMaxVoltageChangeTrigger;
654  };
655 
656  phidget_voltage_input_node(
657  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
658  : phidget_node{hdl, dev, parent}
659  {
660  }
661 
662  void init()
663  {
664  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
665  m_device.on_parameter_created(*m_parameter);
666  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
667  add_child_simple(
668  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
669  add_child_simple(std::make_unique<ossia::phidget_control_node>(
670  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
671  add_child_simple(std::make_unique<ossia::phidget_control_node>(
672  Control_Double_parameter<trigger_desc>{}, "trigger", m_hdl, m_device, *this));
673  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
674  bool b = ossia::convert<bool>(val);
675  if(b)
676  {
677  m_children[2]->get_parameter()->push_value();
678  m_children[3]->get_parameter()->push_value();
679  }
680  });
681  }
682 };
683 
684 class phidget_capacitive_touch_input_node : public ossia::phidget_node
685 {
686 public:
687  struct param_desc
688  {
689  using handle_type = PhidgetCapacitiveTouchHandle;
690  inline static const auto Get = PhidgetCapacitiveTouch_getTouchValue;
691  inline static const auto Change = PhidgetCapacitiveTouch_setOnTouchHandler;
692  inline static const auto Min = PhidgetCapacitiveTouch_getMinTouchValue;
693  inline static const auto Max = PhidgetCapacitiveTouch_getMaxTouchValue;
694  };
695 
696  struct rate_desc
697  {
698  using handle_type = PhidgetCapacitiveTouchHandle;
699  inline static const auto Get = PhidgetCapacitiveTouch_getDataInterval;
700  inline static const auto Set = PhidgetCapacitiveTouch_setDataInterval;
701  inline static const auto Min = PhidgetCapacitiveTouch_getMinDataInterval;
702  inline static const auto Max = PhidgetCapacitiveTouch_getMaxDataInterval;
703  };
704 
705  phidget_capacitive_touch_input_node(
706  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
707  : phidget_node{hdl, dev, parent}
708  {
709  }
710 
711  void init()
712  {
713  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
714  m_device.on_parameter_created(*m_parameter);
715  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
716  add_child_simple(
717  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
718  add_child_simple(std::make_unique<ossia::phidget_control_node>(
719  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
720  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
721  bool b = ossia::convert<bool>(val);
722  if(b)
723  {
724  m_children[2]->get_parameter()->push_value();
725  }
726  });
727  }
728 };
729 
730 class phidget_distance_sensor_node : public ossia::phidget_node
731 {
732 public:
733  struct param_desc
734  {
735  using handle_type = PhidgetDistanceSensorHandle;
736  inline static const auto Get = PhidgetDistanceSensor_getDistance;
737  inline static const auto Change = PhidgetDistanceSensor_setOnDistanceChangeHandler;
738  inline static const auto Min = PhidgetDistanceSensor_getMinDistance;
739  inline static const auto Max = PhidgetDistanceSensor_getMaxDistance;
740  };
741 
742  struct rate_desc
743  {
744  using handle_type = PhidgetDistanceSensorHandle;
745  inline static const auto Get = PhidgetDistanceSensor_getDataInterval;
746  inline static const auto Set = PhidgetDistanceSensor_setDataInterval;
747  inline static const auto Min = PhidgetDistanceSensor_getMinDataInterval;
748  inline static const auto Max = PhidgetDistanceSensor_getMaxDataInterval;
749  };
750 
751  phidget_distance_sensor_node(
752  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
753  : phidget_node{hdl, dev, parent}
754  {
755  }
756 
757  void init()
758  {
759  m_parameter = make_parameter<UInt_parameter<param_desc>>(*this);
760  m_device.on_parameter_created(*m_parameter);
761  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
762  add_child_simple(
763  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
764  add_child_simple(std::make_unique<ossia::phidget_control_node>(
765  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
766  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
767  bool b = ossia::convert<bool>(val);
768  if(b)
769  {
770  m_children[2]->get_parameter()->push_value();
771  }
772  });
773  }
774 };
775 
776 class phidget_humidity_sensor_node : public ossia::phidget_node
777 {
778 public:
779  struct param_desc
780  {
781  using handle_type = PhidgetHumiditySensorHandle;
782  inline static const auto Get = PhidgetHumiditySensor_getHumidity;
783  inline static const auto Change = PhidgetHumiditySensor_setOnHumidityChangeHandler;
784  inline static const auto Min = PhidgetHumiditySensor_getMinHumidity;
785  inline static const auto Max = PhidgetHumiditySensor_getMaxHumidity;
786  };
787 
788  struct rate_desc
789  {
790  using handle_type = PhidgetHumiditySensorHandle;
791  inline static const auto Get = PhidgetHumiditySensor_getDataInterval;
792  inline static const auto Set = PhidgetHumiditySensor_setDataInterval;
793  inline static const auto Min = PhidgetHumiditySensor_getMinDataInterval;
794  inline static const auto Max = PhidgetHumiditySensor_getMaxDataInterval;
795  };
796 
797  phidget_humidity_sensor_node(
798  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
799  : phidget_node{hdl, dev, parent}
800  {
801  }
802 
803  void init()
804  {
805  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
806  m_device.on_parameter_created(*m_parameter);
807  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
808  add_child_simple(
809  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
810  add_child_simple(std::make_unique<ossia::phidget_control_node>(
811  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
812  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
813  bool b = ossia::convert<bool>(val);
814  if(b)
815  {
816  m_children[2]->get_parameter()->push_value();
817  }
818  });
819  }
820 };
821 
822 class phidget_pressure_sensor_node : public ossia::phidget_node
823 {
824 public:
825  struct param_desc
826  {
827  using handle_type = PhidgetPressureSensorHandle;
828  inline static const auto Get = PhidgetPressureSensor_getPressure;
829  inline static const auto Change = PhidgetPressureSensor_setOnPressureChangeHandler;
830  inline static const auto Min = PhidgetPressureSensor_getMinPressure;
831  inline static const auto Max = PhidgetPressureSensor_getMaxPressure;
832  };
833 
834  struct rate_desc
835  {
836  using handle_type = PhidgetPressureSensorHandle;
837  inline static const auto Get = PhidgetPressureSensor_getDataInterval;
838  inline static const auto Set = PhidgetPressureSensor_setDataInterval;
839  inline static const auto Min = PhidgetPressureSensor_getMinDataInterval;
840  inline static const auto Max = PhidgetPressureSensor_getMaxDataInterval;
841  };
842 
843  phidget_pressure_sensor_node(
844  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
845  : phidget_node{hdl, dev, parent}
846  {
847  }
848 
849  void init()
850  {
851  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
852  m_device.on_parameter_created(*m_parameter);
853  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
854  add_child_simple(
855  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
856  add_child_simple(std::make_unique<ossia::phidget_control_node>(
857  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
858  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
859  bool b = ossia::convert<bool>(val);
860  if(b)
861  {
862  m_children[2]->get_parameter()->push_value();
863  }
864  });
865  }
866 };
867 class phidget_resistance_input_node : public ossia::phidget_node
868 {
869 public:
870  struct param_desc
871  {
872  using handle_type = PhidgetResistanceInputHandle;
873  inline static const auto Get = PhidgetResistanceInput_getResistance;
874  inline static const auto Change
875  = PhidgetResistanceInput_setOnResistanceChangeHandler;
876  inline static const auto Min = PhidgetResistanceInput_getMinResistance;
877  inline static const auto Max = PhidgetResistanceInput_getMaxResistance;
878  };
879 
880  struct rate_desc
881  {
882  using handle_type = PhidgetResistanceInputHandle;
883  inline static const auto Get = PhidgetResistanceInput_getDataInterval;
884  inline static const auto Set = PhidgetResistanceInput_setDataInterval;
885  inline static const auto Min = PhidgetResistanceInput_getMinDataInterval;
886  inline static const auto Max = PhidgetResistanceInput_getMaxDataInterval;
887  };
888 
889  phidget_resistance_input_node(
890  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
891  : phidget_node{hdl, dev, parent}
892  {
893  }
894 
895  void init()
896  {
897  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
898  m_device.on_parameter_created(*m_parameter);
899  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
900  add_child_simple(
901  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
902  add_child_simple(std::make_unique<ossia::phidget_control_node>(
903  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
904  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
905  bool b = ossia::convert<bool>(val);
906  if(b)
907  {
908  m_children[2]->get_parameter()->push_value();
909  }
910  });
911  }
912 };
913 
914 class phidget_light_sensor_node : public ossia::phidget_node
915 {
916 public:
917  struct param_desc
918  {
919  using handle_type = PhidgetLightSensorHandle;
920  inline static const auto Get = PhidgetLightSensor_getIlluminance;
921  inline static const auto Change = PhidgetLightSensor_setOnIlluminanceChangeHandler;
922  inline static const auto Min = PhidgetLightSensor_getMinIlluminance;
923  inline static const auto Max = PhidgetLightSensor_getMaxIlluminance;
924  };
925 
926  struct rate_desc
927  {
928  using handle_type = PhidgetLightSensorHandle;
929  inline static const auto Get = PhidgetLightSensor_getDataInterval;
930  inline static const auto Set = PhidgetLightSensor_setDataInterval;
931  inline static const auto Min = PhidgetLightSensor_getMinDataInterval;
932  inline static const auto Max = PhidgetLightSensor_getMaxDataInterval;
933  };
934 
935  phidget_light_sensor_node(
936  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
937  : phidget_node{hdl, dev, parent}
938  {
939  }
940 
941  void init()
942  {
943  m_parameter = make_parameter<Double_parameter<param_desc>>(*this);
944  m_device.on_parameter_created(*m_parameter);
945  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
946  add_child_simple(
947  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
948  add_child_simple(std::make_unique<ossia::phidget_control_node>(
949  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
950  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
951  bool b = ossia::convert<bool>(val);
952  if(b)
953  {
954  m_children[2]->get_parameter()->push_value();
955  }
956  });
957  }
958 };
959 
960 class phidget_digital_input_node : public ossia::phidget_node
961 {
962 public:
963  struct Parameter
964  {
965  PhidgetDigitalInputHandle phidget;
966 
967  bool get_value()
968  {
969  int val = 0;
970  PhidgetDigitalInput_getState(phidget, &val);
971  return val == 1;
972  }
973 
974  void set_value(bool) { }
975 
976  ossia::domain get_domain() { return {}; }
977 
978  void enable_callbacks(phidget_generic_parameter<Parameter>& p)
979  {
980  PhidgetDigitalInput_setOnStateChangeHandler(
981  phidget,
982  [](PhidgetDigitalInputHandle ch, void* ctx, const int ratio) {
983  auto& p = *static_cast<phidget_generic_parameter<Parameter>*>(ctx);
984  p.set_value(ratio);
985  },
986  &p);
987  }
988 
989  void disable_callbacks()
990  {
991  PhidgetDigitalInput_setOnStateChangeHandler(phidget, nullptr, nullptr);
992  }
993  };
994 
995  phidget_digital_input_node(
996  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
997  : phidget_node{hdl, dev, parent}
998  {
999  }
1000 
1001  void init()
1002  {
1003  m_parameter = make_parameter<Parameter>(*this);
1004  m_device.on_parameter_created(*m_parameter);
1005  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
1006  add_child_simple(
1007  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
1008  }
1009 };
1010 
1011 class phidget_digital_output_node : public ossia::phidget_node
1012 {
1013 public:
1014  struct Parameter
1015  {
1016  PhidgetDigitalOutputHandle phidget;
1017 
1018  bool get_value()
1019  {
1020  int val = 0;
1021  PhidgetDigitalOutput_getState(phidget, &val);
1022  return val == 1;
1023  }
1024 
1025  void set_value(bool v) { PhidgetDigitalOutput_setState(phidget, (int)v); }
1026 
1027  ossia::domain get_domain() { return {}; }
1028 
1029  void enable_callbacks(phidget_generic_parameter<Parameter>& p) { }
1030 
1031  void disable_callbacks() { }
1032  };
1033 
1034  phidget_digital_output_node(
1035  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
1036  : phidget_node{hdl, dev, parent}
1037  {
1038  }
1039 
1040  void init()
1041  {
1042  m_parameter = make_parameter<Parameter>(*this);
1043  m_device.on_parameter_created(*m_parameter);
1044  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
1045  add_child_simple(
1046  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
1047  }
1048 };
1049 
1050 class phidget_magnetometer_node : public ossia::phidget_node
1051 {
1052 public:
1053  struct param_desc
1054  {
1055  using handle_type = PhidgetMagnetometerHandle;
1056  inline static const auto Get = PhidgetMagnetometer_getMagneticField;
1057  inline static const auto Change
1058  = PhidgetMagnetometer_setOnMagneticFieldChangeHandler;
1059  inline static const auto Min = PhidgetMagnetometer_getMinMagneticField;
1060  inline static const auto Max = PhidgetMagnetometer_getMaxMagneticField;
1061  };
1062  struct rate_desc
1063  {
1064  using handle_type = PhidgetMagnetometerHandle;
1065  inline static const auto Get = PhidgetMagnetometer_getDataInterval;
1066  inline static const auto Set = PhidgetMagnetometer_setDataInterval;
1067  inline static const auto Min = PhidgetMagnetometer_getMinDataInterval;
1068  inline static const auto Max = PhidgetMagnetometer_getMaxDataInterval;
1069  };
1070 
1071  phidget_magnetometer_node(
1072  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
1073  : phidget_node{hdl, dev, parent}
1074  {
1075  }
1076 
1077  void init()
1078  {
1079  m_parameter = make_parameter<Vec3_parameter<param_desc>>(*this);
1080  m_device.on_parameter_created(*m_parameter);
1081  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
1082  add_child_simple(
1083  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
1084  add_child_simple(std::make_unique<ossia::phidget_control_node>(
1085  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
1086  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
1087  bool b = ossia::convert<bool>(val);
1088  if(b)
1089  {
1090  m_children[2]->get_parameter()->push_value();
1091  }
1092  });
1093  }
1094 };
1095 
1096 class phidget_accelerometer_node : public ossia::phidget_node
1097 {
1098 public:
1099  struct param_desc
1100  {
1101  using handle_type = PhidgetAccelerometerHandle;
1102  inline static const auto Get = PhidgetAccelerometer_getAcceleration;
1103  inline static const auto Change
1104  = PhidgetAccelerometer_setOnAccelerationChangeHandler;
1105  inline static const auto Min = PhidgetAccelerometer_getMinAcceleration;
1106  inline static const auto Max = PhidgetAccelerometer_getMaxAcceleration;
1107  };
1108 
1109  struct rate_desc
1110  {
1111  using handle_type = PhidgetAccelerometerHandle;
1112  inline static const auto Get = PhidgetAccelerometer_getDataInterval;
1113  inline static const auto Set = PhidgetAccelerometer_setDataInterval;
1114  inline static const auto Min = PhidgetAccelerometer_getMinDataInterval;
1115  inline static const auto Max = PhidgetAccelerometer_getMaxDataInterval;
1116  };
1117 
1118  phidget_accelerometer_node(
1119  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
1120  : phidget_node{hdl, dev, parent}
1121  {
1122  }
1123 
1124  void init()
1125  {
1126  m_parameter = make_parameter<Vec3_parameter<param_desc>>(*this);
1127  m_device.on_parameter_created(*m_parameter);
1128  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
1129  add_child_simple(
1130  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
1131  add_child_simple(std::make_unique<ossia::phidget_control_node>(
1132  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
1133  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
1134  bool b = ossia::convert<bool>(val);
1135  if(b)
1136  {
1137  m_children[2]->get_parameter()->push_value();
1138  }
1139  });
1140  }
1141 };
1142 
1143 class phidget_gyroscope_node : public ossia::phidget_node
1144 {
1145 public:
1146  struct param_desc
1147  {
1148  using handle_type = PhidgetGyroscopeHandle;
1149  inline static const auto Get = PhidgetGyroscope_getAngularRate;
1150  inline static const auto Change = PhidgetGyroscope_setOnAngularRateUpdateHandler;
1151  inline static const auto Min = PhidgetGyroscope_getMinAngularRate;
1152  inline static const auto Max = PhidgetGyroscope_getMaxAngularRate;
1153  };
1154 
1155  struct rate_desc
1156  {
1157  using handle_type = PhidgetGyroscopeHandle;
1158  inline static const auto Get = PhidgetGyroscope_getDataInterval;
1159  inline static const auto Set = PhidgetGyroscope_setDataInterval;
1160  inline static const auto Min = PhidgetGyroscope_getMinDataInterval;
1161  inline static const auto Max = PhidgetGyroscope_getMaxDataInterval;
1162  };
1163 
1164  phidget_gyroscope_node(
1165  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
1166  : phidget_node{hdl, dev, parent}
1167  {
1168  }
1169 
1170  void init()
1171  {
1172  m_parameter = make_parameter<Vec3_parameter<param_desc>>(*this);
1173  m_device.on_parameter_created(*m_parameter);
1174 
1175  add_child_simple(std::make_unique<ossia::phidget_open_node>(m_hdl, m_device, *this));
1176  add_child_simple(
1177  std::make_unique<ossia::phidget_channel_node>(m_hdl, m_device, *this));
1178  add_child_simple(std::make_unique<ossia::phidget_control_node>(
1179  Control_UInt_parameter<rate_desc>{}, "rate", m_hdl, m_device, *this));
1180  m_children[0]->get_parameter()->add_callback([=](const ossia::value& val) {
1181  bool b = ossia::convert<bool>(val);
1182  if(b)
1183  {
1184  m_children[2]->get_parameter()->push_value();
1185  }
1186  });
1187  }
1188 };
1189 
1190 class phidget_hub_node : public ossia::phidget_node
1191 {
1192 public:
1193  phidget_hub_node(
1194  PhidgetHandle hdl, ossia::net::device_base& dev, ossia::net::node_base& parent)
1195  : phidget_node{hdl, dev, parent}
1196  {
1197  }
1198  void init() { }
1199 };
1200 
1201 template <typename T, typename... Args>
1202 auto make(
1203  PhidgetHandle phid, ossia::net::device_base& dev, ossia::net::node_base& par_node)
1204 {
1205  static std::vector<std::future<void>> vec;
1206  auto node = new T{phid, dev, par_node};
1207  par_node.add_child(std::unique_ptr<phidget_node>(node));
1208 
1209  /*
1210  Phidget_close(phid);
1211  for(int i = 0; i < 10; i++)
1212  {
1213  if(Phidget_openWaitForAttachment(phid, 100) == EPHIDGET_OK)
1214  break;
1215  }
1216  */
1217 
1218  node->init();
1219  // Phidget_close(phid);
1220 
1221  return node;
1222 }
1223 }
void send(Args &&... args)
send Trigger all callbacks
Definition: callback_container.hpp:190
Root of a device tree.
Definition: ossia/network/base/device.hpp:58
The node_base class.
Definition: network/base/node.hpp:48
node_base * add_child(std::unique_ptr< node_base >)
Adds a new child if it can be added.
Definition: node.cpp:140
The parameter_base class.
Definition: ossia/network/base/parameter.hpp:48
ossia::value value(ossia::destination_index) const
Returns the sub-value at the index given by destination_index.
Definition: ossia/network/base/parameter.cpp:31
The value class.
Definition: value.hpp:173
@ Set
Definition: ossia-cpp98.hpp:68
@ Get
Definition: ossia-cpp98.hpp:67
Definition: git_info.h:7
val_type
Enum to represent the types that a value can take.
Definition: parameter_properties.hpp:16
@ BOOL
ossia::impulse
bounding_mode
Address behaviors at crossing domain boundaries.
Definition: parameter_properties.hpp:56
@ CLIP
The bounds are ignored.
constexpr OSSIA_INLINE auto min(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
min function tailored for values
Definition: math.hpp:125
spdlog::logger & logger() noexcept
Where the errors will be logged. Default is stderr.
Definition: context.cpp:104
access_mode
Address behaviors at crossing domain boundaries time.
Definition: parameter_properties.hpp:46
@ GET
The value can be retrieved and changed.
constexpr OSSIA_INLINE auto max(const T a, const U b) noexcept -> typename std::conditional<(sizeof(T) > sizeof(U)), T, U >::type
max function tailored for values
Definition: math.hpp:96
OSSIA_EXPORT void push_value(const ossia::destination &addr, const ossia::value_with_unit &)
Send a value to a given destination.
Definition: ossia/network/base/parameter.cpp:151
OSSIA_EXPORT ossia::value_with_unit get_value(const ossia::destination &addr)
Get the value associated with a destination.
Definition: ossia/network/base/parameter.cpp:144
domain A domain of values
Definition: domain_base.hpp:23