Allolib  1.0
C++ Components For Interactive Multimedia
al_Parameter.hpp
1 #ifndef AL_PARAMETER_H
2 #define AL_PARAMETER_H
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology,
8  UCSB. Copyright (C) 2012-2015. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are
13  met:
14 
15  Redistributions of source code must retain the above copyright
16  notice, this list of conditions and the following disclaimer.
17 
18  Redistributions in binary form must reproduce the above
19  copyright notice, this list of conditions and the following disclaimer in the
20  documentation and/or other materials provided with the
21  distribution.
22 
23  Neither the name of the University of California nor the names
24  of its contributors may be used to endorse or promote products derived from
25  this software without specific prior written permission.
26 
27  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
31  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
34  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 
39  File description:
40  Parameter class that encapsulates communication of float data in a
41  thread safe way to a separate thread (e.g. audio thread) File author(s):
42  AndrĂ©s Cabrera mantaraya36@gmail.com
43 */
44 
45 #include <float.h>
46 
47 #include <algorithm>
48 #include <atomic>
49 #include <cassert>
50 #include <functional>
51 #include <iostream>
52 #include <map>
53 #include <memory>
54 #include <mutex>
55 #include <sstream>
56 #include <string>
57 #include <vector>
58 
59 #include "al/math/al_Vec.hpp"
60 #include "al/protocol/al_OSC.hpp"
61 #include "al/spatial/al_Pose.hpp"
62 #include "al/types/al_Color.hpp"
63 #include "al/types/al_ValueSource.hpp"
64 
65 namespace al {
66 
67 enum class TimeMasterMode {
68  TIME_MASTER_AUDIO,
69  TIME_MASTER_GRAPHICS,
70  TIME_MASTER_UPDATE,
71  TIME_MASTER_FREE,
72  TIME_MASTER_CPU
73 };
74 
75 // ParameterField
76 // @ingroup UI
78 public:
79  typedef enum { FLOAT, INT32, STRING, NULLDATA } ParameterDataType;
80 
81  ParameterField() {
82  mData = nullptr;
83  mType = NULLDATA;
84  }
85 
86  ParameterField(const float value) {
87  mType = FLOAT;
88  mData = new float;
89  *static_cast<float *>(mData) = value;
90  }
91 
92  ParameterField(const double value) {
93  mType = FLOAT;
94  mData = new float;
95  *static_cast<float *>(mData) = float(value);
96  }
97 
98  ParameterField(const int32_t value) {
99  mType = INT32;
100  mData = new int32_t;
101  *static_cast<int32_t *>(mData) = value;
102  }
103 
104  ParameterField(const std::string value) {
105  mType = STRING;
106  mData = new std::string;
107  *static_cast<std::string *>(mData) = value;
108  }
109 
110  ParameterField(const char *value) {
111  mType = STRING;
112  mData = new std::string;
113  *static_cast<std::string *>(mData) = value;
114  }
115 
116  virtual ~ParameterField() {
117  switch (mType) {
118  case FLOAT:
119  delete static_cast<float *>(mData);
120  break;
121  case STRING:
122  delete static_cast<std::string *>(mData);
123  break;
124  case INT32:
125  delete static_cast<int32_t *>(mData);
126  break;
127  case NULLDATA:
128  break;
129  }
130  }
131 
132  // Copy constructor
133  ParameterField(const ParameterField &paramField) : mType(paramField.mType) {
134  switch (mType) {
135  case FLOAT:
136  mData = new float;
137  *static_cast<float *>(mData) = *static_cast<float *>(paramField.mData);
138  break;
139  case STRING:
140  mData = new std::string;
141  *static_cast<std::string *>(mData) =
142  *static_cast<std::string *>(paramField.mData);
143  break;
144  case INT32:
145  mData = new int32_t;
146  *static_cast<int32_t *>(mData) =
147  *static_cast<int32_t *>(paramField.mData);
148  break;
149  case NULLDATA:
150  break;
151  }
152  }
153 
154  // Move constructor
155  ParameterField(ParameterField &&that) noexcept
156  : mType(NULLDATA), mData(nullptr) {
157  swap(*this, that);
158  }
159 
160  // Copy assignment operator
161  ParameterField &operator=(const ParameterField &other) {
162  ParameterField copy(other);
163  swap(*this, copy);
164  return *this;
165  }
166 
167  // Move assignment operator
168  ParameterField &operator=(ParameterField &&that) {
169  swap(*this, that);
170  return *this;
171  }
172 
173  friend void swap(ParameterField &lhs, ParameterField &rhs) noexcept {
174  std::swap(lhs.mData, rhs.mData);
175  std::swap(lhs.mType, rhs.mType);
176  }
177 
178  ParameterDataType type() { return mType; }
179 
180  template <typename type> type get() { return *static_cast<type *>(mData); }
181 
182  template <typename type> void set(type value) {
183  if (std::is_same<type, float>::value) {
184  if (mType == FLOAT) {
185  *static_cast<type *>(mData) = value;
186  } else {
187  std::cerr
188  << "ERROR: Unexpected type for parameter field set(). Ignoring."
189  << std::endl;
190  }
191  } else if (std::is_same<type, double>::value) {
192  if (mType == FLOAT) {
193  *static_cast<float *>(mData) = value;
194  } else {
195  std::cerr
196  << "ERROR: Unexpected type for parameter field set(). Ignoring."
197  << std::endl;
198  }
199  } else if (std::is_same<type, std::string>::value) {
200  if (mType == STRING) {
201  *static_cast<type *>(mData) = value;
202  } else {
203  std::cerr
204  << "ERROR: Unexpected type for parameter field set(). Ignoring."
205  << std::endl;
206  }
207  } else if (std::is_same<type, char *>::value) {
208  if (mType == STRING) {
209  *static_cast<std::string *>(mData) = value;
210  } else {
211  std::cerr
212  << "ERROR: Unexpected type for parameter field set(). Ignoring."
213  << std::endl;
214  }
215  } else if (std::is_same<type, int32_t>::value) {
216  if (mType == INT32) {
217  *static_cast<type *>(mData) = value;
218  } else {
219  std::cerr
220  << "ERROR: Unexpected type for parameter field set(). Ignoring."
221  << std::endl;
222  }
223  } else if (std::is_same<type, int>::value) {
224  if (mType == INT32) {
225  *static_cast<int32_t *>(mData) = value;
226  } else {
227  std::cerr
228  << "ERROR: Unexpected type for parameter field set(). Ignoring."
229  << std::endl;
230  }
231  }
232  }
233 
234 private:
235  ParameterDataType mType;
236  void *mData;
237 };
238 
239 class Parameter;
240 
247 public:
254  ParameterMeta(std::string parameterName, std::string group = "");
255 
256  virtual ~ParameterMeta() {}
257 
258  // Don't allow copy
259  ParameterMeta(const ParameterMeta &) = delete;
260 
267  std::string getFullAddress() { return mFullAddress; }
268 
272  std::string getName() { return mParameterName; }
273 
277  std::string displayName() { return mDisplayName; }
278 
282  void displayName(std::string displayName) { mDisplayName = displayName; }
283 
287  std::string getGroup() { return mGroup; }
288 
294  virtual float toFloat() { return 0.f; }
295 
303  virtual bool fromFloat(float value) {
304  (void)value;
305  return false;
306  }
307 
308  void setHint(std::string hintName, float hintValue) {
309  mHints[hintName] = hintValue;
310  }
311 
312  float getHint(std::string hintName, bool *exists = nullptr) {
313  float value = 0.0f;
314  if (mHints.find(hintName) != mHints.end()) {
315  value = mHints[hintName];
316  if (exists) {
317  *exists = true;
318  }
319  } else {
320  if (exists) {
321  *exists = false;
322  }
323  }
324 
325  return value;
326  }
327 
328  virtual void getFields(std::vector<ParameterField> & /*fields*/) {
329  std::cout
330  << "get(std::vector<ParameteterField> &fields) not implemented for "
331  << typeid(*this).name() << std::endl;
332  }
333 
334  virtual void setFields(std::vector<ParameterField> & /*fields*/) {
335  std::cout
336  << "set(std::vector<ParameteterField> &fields) not implemented for "
337  << typeid(*this).name() << std::endl;
338  }
339 
340  virtual void sendValue(osc::Send &sender, std::string prefix = "") {
341  (void)prefix; // Remove compiler warning
342  std::cout << "sendValue function not implemented for "
343  << typeid(*this).name() << std::endl;
344  }
345 
346  virtual void sendMeta(osc::Send &sender, std::string bundleName = "",
347  std::string id = "") {
348  (void)bundleName; // Remove compiler warning
349  std::cout << "sendMeta function not implemented for "
350  << typeid(*this).name() << std::endl;
351  }
352 
353  void set(ParameterMeta *p);
354 
355 protected:
356  std::string mFullAddress;
357  std::string mParameterName;
358  std::string mDisplayName;
359  std::string mGroup;
360 
361  std::map<std::string, float> mHints; // Provide hints for behavior
362 };
363 
369 template <class ParameterType> class ParameterWrapper : public ParameterMeta {
370 public:
387  ParameterWrapper(std::string parameterName, std::string group = "",
388  ParameterType defaultValue = ParameterType());
389 
390  ParameterWrapper(std::string parameterName, std::string Group,
391  ParameterType defaultValue, ParameterType min,
392  ParameterType max);
393 
394  ParameterWrapper(const ParameterWrapper &param);
395 
396  virtual ~ParameterWrapper();
397 
405  virtual void set(ParameterType value, ValueSource *src = nullptr) {
406  // if (value > mMax) value = mMax;
407  // if (value < mMin) value = mMin;
408  mValueCache = get();
409  if (mProcessCallback) {
410  value = (*mProcessCallback)(value); //, mProcessUdata);
411  }
412 
413  runChangeCallbacksSynchronous(value, src);
414  setLocking(value);
415  }
416 
420  virtual void reset() { set(mDefault); }
421 
436  virtual void setNoCalls(ParameterType value, void *blockReceiver = nullptr) {
437  // if (value > mMax) value = mMax;
438  // if (value < mMin) value = mMin;
439  mValueCache = get();
440  if (mProcessCallback) {
441  value = (*mProcessCallback)(value); //, mProcessUdata);
442  }
443  if (blockReceiver) {
444  for (auto cb : mCallbacks) {
445  (*cb)(value);
446  }
447  }
448  setLocking(value);
449  mChanged = true;
450  }
451 
457  inline void setLocking(ParameterType value) {
458  mMutex->lock();
459  mValue = value;
460  mMutex->unlock();
461  }
462 
470  virtual ParameterType get();
471 
479  virtual ParameterType getPrevious();
480 
487  void min(ParameterType minValue, ValueSource *src = nullptr) {
488  mMin = minValue;
489  for (auto cb : mMetaCallbacksSrc) {
490  (*cb)(src);
491  }
492  }
493  ParameterType min() const { return mMin; }
494 
501  void max(ParameterType maxValue, ValueSource *src = nullptr) {
502  mMax = maxValue;
503  for (auto cb : mMetaCallbacksSrc) {
504  (*cb)(src);
505  }
506  }
507  ParameterType max() const { return mMax; }
508 
509  void setDefault(const ParameterType &defaultValue) {
510  mDefault = defaultValue;
511  }
512  ParameterType getDefault() const { return mDefault; }
513 
514  // typedef ParameterType (*ParameterProcessCallback)(ParameterType value, void
515  // *userData); typedef void (*ParameterChangeCallback)(ParameterType value,
516  // void *sender, void *userData, void * blockSender);
517 
518  typedef const std::function<ParameterType(ParameterType)>
519  ParameterProcessCallback;
520  typedef const std::function<void(ParameterType)> ParameterChangeCallback;
521  typedef const std::function<void(ParameterType, ValueSource *)>
522  ParameterChangeCallbackSrc;
523 
524  typedef const std::function<void(ValueSource *)>
525  ParameterMetaChangeCallbackSrc;
526 
542  void setProcessingCallback(ParameterProcessCallback cb);
543 
553  void registerChangeCallback(ParameterChangeCallback cb);
554 
555  void registerChangeCallback(ParameterChangeCallbackSrc cb);
556 
557  void registerMetaChangeCallback(ParameterMetaChangeCallbackSrc cb);
558 
573  void setSynchronousCallbacks(bool synchronous = true) {
574  if (mCallbacks.size() > 0 && mCallbacks[0] == nullptr) {
575  if (synchronous) {
576  mCallbacks.erase(mCallbacks.begin());
577  }
578  }
579  if (!synchronous) {
580  mCallbacks.insert(mCallbacks.begin(), nullptr);
581  }
582  }
583 
584  bool hasChange() { return mChanged; }
585 
589  bool processChange() {
590  if (!mChanged) {
591  return false;
592  }
593  ParameterType value = get();
594  mChanged = false;
595 
596  auto callbackIt = mCallbacks.begin();
597  while (callbackIt != mCallbacks.end()) {
598  if (*callbackIt) {
599  (*(*callbackIt))(value);
600  }
601  callbackIt++;
602  }
603  auto callbackSrcIt = mCallbacksSrc.begin();
604  while (callbackSrcIt != mCallbacksSrc.end()) {
605  if (*callbackSrcIt) {
606  (*(*callbackSrcIt))(value, nullptr);
607  }
608  callbackSrcIt++;
609  }
610  return true;
611  }
612 
613  std::vector<ParameterWrapper<ParameterType> *>
614  operator<<(ParameterWrapper<ParameterType> &newParam) {
615  std::vector<ParameterWrapper<ParameterType> *> paramList;
616  paramList.push_back(&newParam);
617  return paramList;
618  }
619 
620  std::vector<ParameterWrapper<ParameterType> *> &
621  operator<<(std::vector<ParameterWrapper<ParameterType> *> &paramVector) {
622  paramVector.push_back(this);
623  return paramVector;
624  }
625 
626  // Allow automatic conversion to the data type
627  // this allows e.g. float value = parameter;
628  operator ParameterType() { return this->get(); }
629 
630  ParameterWrapper<ParameterType> operator=(const ParameterType value) {
631  this->set(value);
632  return *this;
633  }
634 
635 protected:
636  ParameterType mMin;
637  ParameterType mMax;
638 
639  ParameterType mValue;
640  ParameterType mValueCache;
641 
642  ParameterType mDefault;
643 
644  void runChangeCallbacksSynchronous(ParameterType &value, ValueSource *src);
645 
646  std::shared_ptr<ParameterProcessCallback> mProcessCallback;
647  // void * mProcessUdata;
648  // std::vector<void *> mCallbackUdata;
649 
650  bool mChanged{false};
651 
652 private:
653  // pointer to avoid having to explicitly declare copy/move
654  std::unique_ptr<std::mutex> mMutex;
655 
656 private:
657  std::vector<std::shared_ptr<ParameterChangeCallback>> mCallbacks;
658  std::vector<std::shared_ptr<ParameterChangeCallbackSrc>> mCallbacksSrc;
659 
660  std::vector<std::shared_ptr<ParameterMetaChangeCallbackSrc>>
661  mMetaCallbacksSrc;
662 };
663 
696 class Parameter : public ParameterWrapper<float> {
697 public:
711  Parameter(std::string parameterName, std::string group = "",
712  float defaultValue = 0, float min = -99999.0, float max = 99999.0);
713 
714  Parameter(std::string parameterName, float defaultValue, float min = -99999.0,
715  float max = 99999.0);
716 
717  [[deprecated("Prefix is ignored")]] Parameter(
718  std::string parameterName, std::string Group, float defaultValue,
719  std::string prefix, float min = -99999.0, float max = 99999.0);
720 
721  Parameter(const al::Parameter &param) : ParameterWrapper<float>(param) {
722  mValue = param.mValue;
723  setDefault(param.getDefault());
724  }
725 
732  virtual void set(float value, ValueSource *src = nullptr) override;
733 
742  virtual void setNoCalls(float value, void *blockReceiver = nullptr) override;
743 
751  virtual float get() override;
752 
753  virtual float toFloat() override { return mValue; }
754 
755  virtual bool fromFloat(float value) override {
756  set(value);
757  return true;
758  }
759 
760  float operator=(const float value) {
761  this->set(value);
762  return value;
763  }
764 
765  virtual void getFields(std::vector<ParameterField> &fields) override {
766  fields.emplace_back(ParameterField(get()));
767  }
768 
769  virtual void setFields(std::vector<ParameterField> &fields) override {
770  assert(fields.size() == 1);
771  if (fields.size() == 1) {
772  assert(fields[0].type() == ParameterField::FLOAT);
773  set(fields[0].get<float>());
774  } else {
775  std::cout << "Wrong number of parameters for " << getFullAddress()
776  << std::endl;
777  }
778  }
779 
780  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
781  sender.send(prefix + getFullAddress(), get());
782  }
783 
784  virtual void sendMeta(osc::Send &sender, std::string bundleName = "",
785  std::string id = "") override {
786  if (bundleName.size() == 0) {
787  sender.send("/registerParameter", getName(), getGroup(), getDefault(),
788  std::string(), min(), max());
789  } else {
790  sender.send("/registerBundleParameter", bundleName, id, getName(),
791  getGroup(), getDefault(), std::string(), min(), max());
792  }
793  }
794 
795 private:
796 };
797 
800 class ParameterInt : public ParameterWrapper<int32_t> {
801 public:
816  ParameterInt(std::string parameterName, std::string Group = "",
817  int32_t defaultValue = 0, int32_t min = 0, int32_t max = 127);
818 
819  [[deprecated("Prefix is ignored")]] ParameterInt(
820  std::string parameterName, std::string Group, int32_t defaultValue,
821  std::string prefix, int32_t min = 0, int32_t max = 127);
822 
823  ParameterInt(const al::ParameterInt &param)
824  : ParameterWrapper<int32_t>(param) {
825  mValue = param.mValue;
826  setDefault(param.getDefault());
827  }
828 
835  virtual void set(int32_t value, ValueSource *src = nullptr) override;
836 
845  virtual void setNoCalls(int32_t value,
846  void *blockReceiver = nullptr) override;
847 
848  // /**
849  // * @brief get the parameter's value
850  // *
851  // * This function is thread-safe and can be called from any number of
852  // threads
853  // *
854  // * @return the parameter value
855  // */
856  // virtual int32_t get() override;
857 
858  virtual float toFloat() override { return float(mValue); }
859 
860  virtual bool fromFloat(float value) override {
861  set(int32_t(value));
862  return true;
863  }
864 
865  float operator=(const int32_t value) {
866  this->set(value);
867  return float(value);
868  }
869 
870  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
871  sender.send(prefix + getFullAddress(), get());
872  }
873 
874  virtual void getFields(std::vector<ParameterField> &fields) override {
875  fields.emplace_back(ParameterField(get()));
876  }
877 
878  virtual void setFields(std::vector<ParameterField> &fields) override {
879  if (fields.size() == 1) {
880  assert(fields[0].type() == ParameterField::INT32);
881  set(fields[0].get<int32_t>());
882  } else {
883  std::cout << "Wrong number of parameters for " << getFullAddress()
884  << std::endl;
885  }
886  }
887 
888  virtual void sendMeta(osc::Send &sender, std::string bundleName = "",
889  std::string id = "") override {
890  if (bundleName.size() == 0) {
891  sender.send("/registerParameter", getName(), getGroup(), getDefault(),
892  std::string(), min(), max());
893  } else {
894  sender.send("/registerBundleParameter", bundleName, id, getName(),
895  getGroup(), getDefault(), std::string(), min(), max());
896  }
897  }
898 
899 private:
900 };
901 
904 class ParameterBool : public Parameter {
905 public:
906  using Parameter::get;
907  using Parameter::setFields;
923  ParameterBool(std::string parameterName, std::string Group = "",
924  float defaultValue = 0, float min = 0, float max = 1.0);
925 
926  [[deprecated("Prefix is ignored")]] ParameterBool(
927  std::string parameterName, std::string Group, float defaultValue,
928  std::string prefix, float min = 0, float max = 1.0);
929 
930  bool operator=(bool value) {
931  this->set(value ? 1.0f : 0.0f);
932  return value == 1.0;
933  }
934 
935  virtual float toFloat() override { return get(); }
936 
937  virtual bool fromFloat(float value) override {
938  set(value);
939  return true;
940  }
941 
942  virtual void getFields(std::vector<ParameterField> &fields) override {
943  fields.emplace_back(ParameterField(get() == 1.0f ? 1 : 0));
944  }
945 
946  virtual void setFields(std::vector<ParameterField> &fields) override {
947  if (fields.size() == 1) {
948  if (fields[0].type() == ParameterField::INT32) {
949  set(fields[0].get<int32_t>() == 1 ? 1.0f : 0.0f);
950  } else if (fields[0].type() == ParameterField::FLOAT) {
951  set(fields[0].get<float>());
952  }
953  } else {
954  std::cout << "Wrong number of parameters for " << getFullAddress()
955  << std::endl;
956  }
957  }
958 
959  virtual void sendMeta(osc::Send &sender, std::string bundleName = "",
960  std::string id = "") override {
961 
962  if (bundleName.size() == 0) {
963  sender.send("/registerParameter", getName(), getGroup(), getDefault(),
964  std::string(), min(), max());
965  } else {
966  sender.send("/registerBundleParameter", bundleName, id, getName(),
967  getGroup(), getDefault(), std::string(), min(), max());
968  }
969  }
970 };
971 
972 // Symbolizes a distributed action that
973 // has no value per se, but that can be used to trigger actions
974 class Trigger : public ParameterWrapper<bool> {
975 public:
976  Trigger(std::string parameterName, std::string Group = "")
977  : ParameterWrapper<bool>(parameterName, Group, false) {
978  mValue = false;
979  mValueCache = false;
980  }
981 
982  virtual float toFloat() override { return get() ? 1.0f : 0.0f; }
983 
984  virtual bool fromFloat(float value) override {
985  set(value != 0.0f);
986  return true;
987  }
988 
989  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
990  sender.send(prefix + getFullAddress());
991  }
992 
993  void trigger() { set(true); }
994 };
995 
996 // These three types are blocking, should not be used in time-critical
997 // contexts like the audio callback. The classes were explicitly defined to
998 // overcome the issues related to the > and < operators needed when validating
999 // minumum and maximum values for the parameter
1000 
1003 class ParameterString : public ParameterWrapper<std::string> {
1004 public:
1007 
1008  ParameterString(std::string parameterName, std::string Group = "",
1009  std::string defaultValue = "")
1010  : ParameterWrapper<std::string>(parameterName, Group, defaultValue) {}
1011 
1012  [[deprecated("Prefix is ignored")]] ParameterString(std::string parameterName,
1013  std::string Group,
1014  std::string defaultValue,
1015  std::string /*prefix*/)
1016  : ParameterWrapper<std::string>(parameterName, Group, defaultValue) {}
1017 
1018  virtual float toFloat() override {
1019  float value = 0.0;
1020  try {
1021  value = std::stof(get());
1022  } catch (...) {
1023  // ignore
1024  }
1025  return value;
1026  }
1027 
1028  virtual bool fromFloat(float value) override {
1029  set(std::to_string(value));
1030  return true;
1031  }
1032 
1033  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
1034  sender.send(prefix + getFullAddress(), get());
1035  }
1036 
1037  virtual void getFields(std::vector<ParameterField> &fields) override {
1038  fields.emplace_back(ParameterField(get()));
1039  }
1040 
1041  virtual void setFields(std::vector<ParameterField> &fields) override {
1042  if (fields.size() == 1) {
1043  set(fields[0].get<std::string>());
1044  } else {
1045  std::cout << "Wrong number of parameters for " << getFullAddress()
1046  << std::endl;
1047  }
1048  }
1049 
1050  virtual void sendMeta(osc::Send &sender, std::string bundleName = "",
1051  std::string id = "") override {
1052  if (bundleName.size() == 0) {
1053  sender.send("/registerParameter", getName(), getGroup(), getDefault(),
1054  std::string(), min(), max());
1055  } else {
1056  sender.send("/registerBundleParameter", bundleName, id, getName(),
1057  getGroup(), getDefault(), std::string(), min(), max());
1058  }
1059  }
1060 };
1061 
1062 class ParameterVec3 : public ParameterWrapper<al::Vec3f> {
1063 public:
1066 
1067  ParameterVec3(std::string parameterName, std::string Group = "",
1068  al::Vec3f defaultValue = al::Vec3f())
1069  : ParameterWrapper<al::Vec3f>(parameterName, Group, defaultValue) {}
1070 
1071  ParameterVec3 operator=(const Vec3f vec) {
1072  this->set(vec);
1073  return *this;
1074  }
1075 
1076  float operator[](size_t index) {
1077  assert(index < INT_MAX); // Hack to remove
1078  Vec3f vec = this->get();
1079  return vec[index];
1080  }
1081 
1082  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
1083  Vec3f vec = get();
1084  sender.send(prefix + getFullAddress(), vec.x, vec.y, vec.z);
1085  }
1086 
1087  virtual void getFields(std::vector<ParameterField> &fields) override {
1088  Vec3f vec = this->get();
1089  fields.emplace_back(ParameterField(vec.x));
1090  fields.emplace_back(ParameterField(vec.y));
1091  fields.emplace_back(ParameterField(vec.z));
1092  }
1093 
1094  virtual void setFields(std::vector<ParameterField> &fields) override {
1095  if (fields.size() == 3) {
1096  Vec3f vec(fields[0].get<float>(), fields[1].get<float>(),
1097  fields[2].get<float>());
1098  set(vec);
1099  } else {
1100  std::cout << "Wrong number of parameters for " << getFullAddress()
1101  << std::endl;
1102  }
1103  }
1104 };
1105 
1108 class ParameterVec4 : public ParameterWrapper<al::Vec4f> {
1109 public:
1112 
1113  ParameterVec4(std::string parameterName, std::string Group = "",
1114  al::Vec4f defaultValue = al::Vec4f())
1115  : ParameterWrapper<al::Vec4f>(parameterName, Group, defaultValue) {}
1116 
1117  ParameterVec4 operator=(const Vec4f vec) {
1118  this->set(vec);
1119  return *this;
1120  }
1121 
1122  float operator[](size_t index) {
1123  Vec4f vec = this->get();
1124  return vec[index];
1125  }
1126 
1127  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
1128  Vec4f vec = get();
1129  sender.send(prefix + getFullAddress(), vec.x, vec.y, vec.z, vec.w);
1130  }
1131 
1132  virtual void getFields(std::vector<ParameterField> &fields) override {
1133  Vec4f vec = this->get();
1134  fields.emplace_back(ParameterField(vec.x));
1135  fields.emplace_back(ParameterField(vec.y));
1136  fields.emplace_back(ParameterField(vec.z));
1137  fields.emplace_back(ParameterField(vec.w));
1138  }
1139 
1140  virtual void setFields(std::vector<ParameterField> &fields) override {
1141  if (fields.size() == 4) {
1142  Vec4f vec(fields[0].get<float>(), fields[1].get<float>(),
1143  fields[2].get<float>(), fields[3].get<float>());
1144  set(vec);
1145  } else {
1146  std::cout << "Wrong number of parameters for " << getFullAddress()
1147  << std::endl;
1148  }
1149  }
1150 };
1151 
1154 class ParameterPose : public ParameterWrapper<al::Pose> {
1155 public:
1158 
1159  ParameterPose(std::string parameterName, std::string Group = "",
1160  al::Pose defaultValue = al::Pose())
1161  : ParameterWrapper<al::Pose>(parameterName, Group, defaultValue) {}
1162 
1163  al::Pose operator=(const al::Pose vec) {
1164  this->set(vec);
1165  return *this;
1166  }
1167 
1168  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
1169  Pose pose = get();
1170  Quatd q = pose.quat();
1171  sender.send(prefix + getFullAddress(), float(pose.x()), float(pose.y()),
1172  float(pose.z()), float(q.w), float(q.x), float(q.y),
1173  float(q.z));
1174  }
1175 
1176  void setPos(const al::Vec3d v) { this->set(al::Pose(v, this->get().quat())); }
1177  void setQuat(const al::Quatd q) { this->set(al::Pose(this->get().pos(), q)); }
1178  // float operator[](size_t index) { Pose vec = this->get(); return
1179  // vec[index];}
1180 
1181  virtual void getFields(std::vector<ParameterField> &fields) override {
1182  Quatf quat = get().quat();
1183  Vec4f pos = get().pos();
1184  fields.reserve(7);
1185  fields.emplace_back(ParameterField(pos.x));
1186  fields.emplace_back(ParameterField(pos.y));
1187  fields.emplace_back(ParameterField(pos.z));
1188  fields.emplace_back(ParameterField(quat.w));
1189  fields.emplace_back(ParameterField(quat.x));
1190  fields.emplace_back(ParameterField(quat.y));
1191  fields.emplace_back(ParameterField(quat.z));
1192  }
1193 
1194  virtual void setFields(std::vector<ParameterField> &fields) override {
1195  if (fields.size() == 7) {
1196  Pose vec(Vec3f(fields[0].get<float>(), fields[1].get<float>(),
1197  fields[2].get<float>()),
1198  Quatf(fields[3].get<float>(), fields[4].get<float>(),
1199  fields[5].get<float>(), fields[6].get<float>()));
1200  set(vec);
1201  } else {
1202  std::cout << "Wrong number of parameters for " << getFullAddress()
1203  << std::endl;
1204  }
1205  }
1206 };
1207 
1210 class ParameterMenu : public ParameterWrapper<int32_t> {
1211 public:
1214 
1215  ParameterMenu(std::string parameterName, std::string Group = "",
1216  int defaultValue = 0)
1217  : ParameterWrapper<int>(parameterName, Group, defaultValue) {}
1218 
1219  int operator=(const int32_t value) {
1220  this->set(value);
1221  return *this;
1222  }
1223 
1224  void setElements(std::vector<std::string> elements) {
1225  std::lock_guard<std::mutex> lk(mElementsLock);
1226  mElements = elements;
1227  }
1228 
1229  std::vector<std::string> getElements() {
1230  std::lock_guard<std::mutex> lk(mElementsLock);
1231  return mElements;
1232  }
1233 
1234  std::string getCurrent() {
1235  int current = get();
1236  std::lock_guard<std::mutex> lk(mElementsLock);
1237  if (mElements.size() > 0 && current >= 0 &&
1238  current < int32_t(mElements.size())) {
1239  return mElements[current];
1240  } else {
1241  return "";
1242  }
1243  }
1244 
1245  void setCurrent(std::string element, bool noCalls = false) {
1246  mElementsLock.lock();
1247  auto position = std::find(mElements.begin(), mElements.end(), element);
1248  bool found = position != mElements.end();
1249  int foundPosition = (int32_t)std::distance(mElements.begin(), position);
1250  mElementsLock.unlock();
1251  if (found) {
1252  if (noCalls) {
1253  setNoCalls(foundPosition);
1254  } else {
1255  set(foundPosition);
1256  }
1257  } else {
1258  std::cerr << "ERROR: Could not find element: " << element << std::endl;
1259  }
1260  }
1261 
1262  virtual float toFloat() override {
1263  return float(get());
1264  // return std::stof(getCurrent());
1265  }
1266 
1267  virtual bool fromFloat(float value) override {
1268  set((int32_t)value);
1269  return true;
1270  }
1271 
1272  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
1273  sender.send(prefix + getFullAddress(), get());
1274  }
1275 
1276  virtual void getFields(std::vector<ParameterField> &fields) override {
1277  fields.emplace_back(ParameterField(getCurrent()));
1278  }
1279 
1280  virtual void setFields(std::vector<ParameterField> &fields) override {
1281  // TODO an option should be added to allow storing the current element as
1282  // index instead of text.
1283  if (fields.size() == 1) {
1284  setCurrent(fields[0].get<std::string>());
1285  } else {
1286  std::cout << "Wrong number of parameters for " << getFullAddress()
1287  << std::endl;
1288  }
1289  }
1290 
1291 private:
1292  std::mutex mElementsLock;
1293  std::vector<std::string> mElements;
1294 };
1295 
1304 class ParameterChoice : public ParameterWrapper<uint64_t> {
1305 public:
1308 
1309  ParameterChoice(std::string parameterName, std::string Group = "",
1310  uint64_t defaultValue = 0)
1311  : ParameterWrapper<uint64_t>(parameterName, Group, defaultValue) {}
1312 
1313  ParameterChoice &operator=(const uint64_t value) {
1314  this->set(value);
1315  return *this;
1316  }
1317 
1318  void setElements(std::vector<std::string> &elements, bool allOn = false) {
1319  mElements = elements;
1320  min(0);
1321  assert(((uint64_t)1 << (elements.size() - 1)) < UINT64_MAX);
1322  max((uint64_t)1 << (elements.size() - 1));
1323  if (allOn) {
1324  uint16_t value = 0;
1325  for (unsigned int i = 0; i < elements.size(); i++) {
1326  value |= 1 << i;
1327  }
1328  set(value);
1329  }
1330  }
1331 
1332  void setElementSelected(std::string name, bool selected = true) {
1333  for (size_t i = 0; i < mElements.size(); i++) {
1334  if (mElements[i] == name) {
1335  uint64_t value = get();
1336  if (selected) {
1337  value |= UINT64_C(1) << i;
1338  } else {
1339  value ^= value | UINT64_C(1) << i;
1340  }
1341  set(value);
1342  }
1343  }
1344  }
1345 
1346  std::vector<std::string> getElements() { return mElements; }
1347 
1348  std::vector<std::string> getSelectedElements() {
1349  std::vector<std::string> selected;
1350  for (uint64_t i = 0; i < mElements.size(); i++) {
1351  if (get() & ((uint64_t)1 << i)) {
1352  if (mElements.size() > i) {
1353  selected.push_back(mElements[i]);
1354  }
1355  }
1356  }
1357  return selected;
1358  }
1359 
1360  void set(std::vector<int8_t> on) {
1361  uint64_t value = 0;
1362  for (auto onBit : on) {
1363  if (onBit < 64) {
1364  value |= UINT64_C(1) << onBit;
1365  } else {
1366  std::cerr << __FILE__ << " " << __FUNCTION__
1367  << " bit index too high. Ignoring" << std::endl;
1368  }
1369  }
1370  set(value);
1371  }
1372 
1373  virtual float toFloat() override {
1374  return (float)get();
1375  // return std::stof(getCurrent());
1376  }
1377 
1378  virtual bool fromFloat(float value) override {
1379  set((uint64_t)value);
1380  return true;
1381  }
1382 
1383  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
1384  sender.send(prefix + getFullAddress(), (int32_t)get());
1385  }
1386 
1387  virtual void getFields(std::vector<ParameterField> &fields) override {
1388  if (get() > INT32_MAX) {
1389  std::cerr << "WARNING: Can't fit choice value." << std::endl;
1390  }
1391  fields.emplace_back(ParameterField((int32_t)get()));
1392  }
1393 
1394  virtual void setFields(std::vector<ParameterField> &fields) override {
1395  // TODO an option should be added to allow storing the current element as
1396  // index instead of text.
1397  if (fields.size() == 1) {
1398  set(fields[0].get<int32_t>());
1399  } else {
1400  std::cout << "Wrong number of parameters for " << getFullAddress()
1401  << std::endl;
1402  }
1403  }
1404 
1405 private:
1406  std::vector<std::string> mElements;
1407 };
1408 
1411 class ParameterColor : public ParameterWrapper<al::Color> {
1412 public:
1415 
1416  ParameterColor(std::string parameterName, std::string Group = "",
1417  al::Color defaultValue = al::Color())
1418  : ParameterWrapper<al::Color>(parameterName, Group, defaultValue) {}
1419 
1420  ParameterColor operator=(const al::Color vec) {
1421  this->set(vec);
1422  return *this;
1423  }
1424 
1425  virtual void sendValue(osc::Send &sender, std::string prefix = "") override {
1426  Color c = get();
1427  sender.send(prefix + getFullAddress(), c.r, c.g, c.b, c.a);
1428  }
1429 
1430  virtual void getFields(std::vector<ParameterField> &fields) override {
1431  Color vec = this->get();
1432  fields.emplace_back(ParameterField(vec.r));
1433  fields.emplace_back(ParameterField(vec.g));
1434  fields.emplace_back(ParameterField(vec.b));
1435  fields.emplace_back(ParameterField(vec.a));
1436  }
1437 
1438  virtual void setFields(std::vector<ParameterField> &fields) override {
1439  if (fields.size() == 4) {
1440  Color vec(fields[0].get<float>(), fields[1].get<float>(),
1441  fields[2].get<float>(), fields[3].get<float>());
1442  set(vec);
1443  } else {
1444  std::cout << "Wrong number of parameters for " << getFullAddress()
1445  << std::endl;
1446  }
1447  }
1448 };
1449 
1450 // Implementations -----------------------------------------------------------
1451 
1452 template <class ParameterType>
1454  // delete mMutex;
1455 }
1456 
1457 template <class ParameterType>
1459  std::string group,
1460  ParameterType defaultValue)
1461  : ParameterMeta(parameterName, group), mProcessCallback(nullptr) {
1462  mValue = defaultValue;
1463  mValueCache = defaultValue;
1464  mMutex = std::make_unique<std::mutex>();
1465  setDefault(defaultValue);
1466  std::shared_ptr<ParameterChangeCallback> mAsyncCallback =
1467  std::make_shared<ParameterChangeCallback>(
1468  [&](ParameterType value) { mChanged = true; });
1469 }
1470 
1471 template <class ParameterType>
1472 ParameterWrapper<ParameterType>::ParameterWrapper(std::string parameterName,
1473  std::string group,
1474  ParameterType defaultValue,
1475  ParameterType min,
1476  ParameterType max)
1477  : ParameterWrapper<ParameterType>::ParameterWrapper(parameterName, group,
1478  defaultValue) {
1479  mMin = min;
1480  mMax = max;
1481  mMutex = std::make_unique<std::mutex>();
1482  setDefault(defaultValue);
1483 }
1484 
1485 template <class ParameterType>
1487  const ParameterWrapper<ParameterType> &param)
1488  : ParameterMeta(param.mParameterName, param.mGroup) {
1489  mMin = param.mMin;
1490  mMax = param.mMax;
1491  mProcessCallback = param.mProcessCallback;
1492  // mProcessUdata = param.mProcessUdata;
1493  mCallbacks = param.mCallbacks;
1494  mMutex = std::make_unique<std::mutex>();
1495  setDefault(param.getDefault());
1496  // mCallbackUdata = param.mCallbackUdata;
1497 }
1498 
1499 template <class ParameterType>
1501  ParameterType current = mValueCache;
1502  if (mMutex->try_lock()) {
1503  current = mValue;
1504  mMutex->unlock();
1505  }
1506  return current;
1507 }
1508 
1509 template <class ParameterType>
1511  return mValueCache;
1512 }
1513 
1514 template <class ParameterType>
1516  typename ParameterWrapper::ParameterProcessCallback cb) {
1517  mProcessCallback = std::make_shared<ParameterProcessCallback>(cb);
1518  // mProcessUdata = userData;
1519 }
1520 
1521 template <class ParameterType>
1523  ParameterChangeCallback cb) {
1524  mCallbacks.push_back(std::make_shared<ParameterChangeCallback>(cb));
1525  // mCallbackUdata.push_back(userData);
1526 }
1527 
1528 template <class ParameterType>
1530  ParameterChangeCallbackSrc cb) {
1531  mCallbacksSrc.push_back(std::make_shared<ParameterChangeCallbackSrc>(cb));
1532  // mCallbackUdata.push_back(userData);
1533 }
1534 
1535 template <class ParameterType>
1536 void ParameterWrapper<ParameterType>::registerMetaChangeCallback(
1537  ParameterMetaChangeCallbackSrc cb) {
1538  mMetaCallbacksSrc.push_back(
1539  std::make_shared<ParameterMetaChangeCallbackSrc>(cb));
1540 }
1541 
1542 template <class ParameterType>
1543 void ParameterWrapper<ParameterType>::runChangeCallbacksSynchronous(
1544  ParameterType &value, ValueSource *src) {
1545  for (auto cb : mCallbacks) {
1546  if (cb == nullptr) {
1547  // If first callback if nullptr, callbacks must be processed async
1548  mChanged = true;
1549  return;
1550  } else {
1551  (*cb)(value);
1552  }
1553  }
1554  for (auto cb : mCallbacksSrc) {
1555  (*cb)(value, src);
1556  }
1557 }
1558 
1559 } // namespace al
1560 
1561 #endif // AL_PARAMETER_H
virtual float toFloat() override
Generic function to return the value of the parameter as a float.
virtual float get() override
get the parameter's value
ParameterBool(std::string parameterName, std::string Group="", float defaultValue=0, float min=0, float max=1.0)
ParameterBool.
virtual bool fromFloat(float value) override
Generic function to set the parameter from a single float value.
A parameter representing selected items from a list.
virtual float toFloat() override
Generic function to return the value of the parameter as a float.
virtual bool fromFloat(float value) override
Generic function to set the parameter from a single float value.
The Parameter class.
virtual float get() override
get the parameter's value
virtual bool fromFloat(float value) override
Generic function to set the parameter from a single float value.
virtual void set(float value, ValueSource *src=nullptr) override
set the parameter's value
Parameter(std::string parameterName, std::string group="", float defaultValue=0, float min=-99999.0, float max=99999.0)
Parameter.
virtual void setNoCalls(float value, void *blockReceiver=nullptr) override
set the parameter's value without calling callbacks
virtual float toFloat() override
Generic function to return the value of the parameter as a float.
ParameterInt(std::string parameterName, std::string Group="", int32_t defaultValue=0, int32_t min=0, int32_t max=127)
ParameterInt.
virtual void set(int32_t value, ValueSource *src=nullptr) override
set the parameter's value
virtual bool fromFloat(float value) override
Generic function to set the parameter from a single float value.
virtual float toFloat() override
Generic function to return the value of the parameter as a float.
virtual void setNoCalls(int32_t value, void *blockReceiver=nullptr) override
set the parameter's value without calling callbacks
virtual float toFloat() override
Generic function to return the value of the parameter as a float.
virtual bool fromFloat(float value) override
Generic function to set the parameter from a single float value.
The ParameterMeta class defines the base interface for Parameter metadata.
virtual bool fromFloat(float value)
Generic function to set the parameter from a single float value.
std::string displayName()
returns the text that should accompany parameters when displayed
ParameterMeta(std::string parameterName, std::string group="")
ParameterMeta.
std::string getFullAddress()
return the full OSC address for the parameter
void displayName(std::string displayName)
sets the text that should accompany parameters when displayed
std::string getName()
getName returns the name of the parameter
virtual float toFloat()
Generic function to return the value of the parameter as a float.
std::string getGroup()
getGroup returns the name of the group for the parameter
virtual bool fromFloat(float value) override
Generic function to set the parameter from a single float value.
virtual float toFloat() override
Generic function to return the value of the parameter as a float.
The ParameterWrapper class provides a generic thread safe Parameter class from the ParameterType temp...
void setSynchronousCallbacks(bool synchronous=true)
Determines whether value change callbacks are called synchronously.
virtual void setNoCalls(ParameterType value, void *blockReceiver=nullptr)
set the parameter's value without calling callbacks
virtual ParameterType get()
get the parameter's value
void setProcessingCallback(ParameterProcessCallback cb)
setProcessingCallback sets a callback to be called whenever the parameter value changes
bool processChange()
call change callbacks if value has changed since last call
void min(ParameterType minValue, ValueSource *src=nullptr)
set the minimum value for the parameter
virtual void reset()
reset value to default value
ParameterWrapper(std::string parameterName, std::string group="", ParameterType defaultValue=ParameterType())
ParameterWrapper.
void registerChangeCallback(ParameterChangeCallback cb)
registerChangeCallback adds a callback to be called when the value changes
virtual ParameterType getPrevious()
Get previous value.
virtual void set(ParameterType value, ValueSource *src=nullptr)
set the parameter's value
void setLocking(ParameterType value)
set the parameter's value forcing a lock
void max(ParameterType maxValue, ValueSource *src=nullptr)
set the maximum value for the parameter
A local coordinate frame.
Definition: al_Pose.hpp:63
Vec3d & pos()
Get "position" vector.
Definition: al_Pose.hpp:100
Quatd & quat()
Get quaternion component (represents orientation)
Definition: al_Pose.hpp:108
T w
w component
Definition: al_Quat.hpp:67
T x
x component
Definition: al_Quat.hpp:68
T y
y component
Definition: al_Quat.hpp:69
T z
z component
Definition: al_Quat.hpp:70
virtual bool fromFloat(float value) override
Generic function to set the parameter from a single float value.
virtual float toFloat() override
Generic function to return the value of the parameter as a float.
size_t send()
Send and clear current packet contents.
T min(const T &v1, const T &v2, const T &v3)
T max(const T &v1, const T &v2, const T &v3)
Definition: al_App.hpp:23
Quat< float > Quatf
Single-precision quaternion.
Definition: al_Quat.hpp:54
Vec< 3, float > Vec3f
float 3-vector
Definition: al_Vec.hpp:59
float a
Alpha component in [0, 1].
Definition: al_Color.hpp:74
float r
Red component in [0, 1].
Definition: al_Color.hpp:71
float b
Blue component in [0, 1].
Definition: al_Color.hpp:73
float g
Green component in [0, 1].
Definition: al_Color.hpp:72