ape  0.5.0
Audio Programming Environment
label.h
Go to the documentation of this file.
1 #ifndef CPPAPE_LABEL_H
2 #define CPPAPE_LABEL_H
3 
4 #include "baselib.h"
5 #include <vector>
6 
7 namespace ape
8 {
9  namespace detail
10  {
11  template<typename T>
12  struct fmt_type_traits;
13 
14  template<>
15  struct fmt_type_traits<signed int>
16  {
17  static constexpr const char* designator()
18  {
19  return "d";
20  }
21  };
22 
23  template<>
24  struct fmt_type_traits<const char*>
25  {
26  static constexpr const char* designator()
27  {
28  return "s";
29  }
30  };
31 
32  template<>
33  struct fmt_type_traits<void*>
34  {
35  static constexpr const char* designator()
36  {
37  return "x";
38  }
39  };
40 
41  template<>
42  struct fmt_type_traits<unsigned int>
43  {
44  static constexpr const char* designator()
45  {
46  return "u";
47  }
48  };
49 
50  template<>
51  struct fmt_type_traits<float>
52  {
53  static constexpr const char* designator()
54  {
55  return "f";
56  }
57  };
58 
59  template<>
60  struct fmt_type_traits<double>
61  {
62  static constexpr const char* designator()
63  {
64  return "lf";
65  }
66  };
67 
68  template<>
69  struct fmt_type_traits<char>
70  {
71  static constexpr const char* designator()
72  {
73  return "c";
74  }
75  };
76 
77  template<>
78  struct fmt_type_traits<long double>
79  {
80  static constexpr const char* designator()
81  {
82  return "ld";
83  }
84  };
85 
86  template<>
87  struct fmt_type_traits<unsigned long long>
88  {
89  static constexpr const char* designator()
90  {
91  return "lu";
92  }
93  };
94 
95  template<>
96  struct fmt_type_traits<signed long long>
97  {
98  static constexpr const char* designator()
99  {
100  return "li";
101  }
102  };
103 
104  class ControlBlockBase
105  {
106  public:
107 
108  class Handle
109  {
110  public:
111  friend class ControlBlockBase;
112 
113  ~Handle()
114  {
115  parent->decRef();
116  }
117 
118  Handle(Handle&& other) = default;
119  Handle& operator = (Handle&& other) = default;
120 
121  Handle(const Handle& other)
122  : parent(other.parent)
123  {
124  parent->addRef();
125  }
126 
127  Handle& operator = (const Handle& other)
128  {
129  other.parent->addRef();
130  parent->decRef();
131  parent = other.parent;
132  return *this;
133  }
134 
135  private:
136 
137  Handle(ControlBlockBase& parent)
138  : parent(&parent)
139  {
140  parent.addRef();
141  }
142 
143  ControlBlockBase* parent;
144  };
145 
146  virtual ~ControlBlockBase() {}
147 
148  Handle handle()
149  {
150  return { *this };
151  }
152 
153  private:
154 
155  void addRef()
156  {
157  counter++;
158  }
159 
160  void decRef()
161  {
162  if (--counter == 0)
163  {
164  delete this;
165  }
166  }
167 
168 
169  std::size_t counter = 0;
170  };
171 
172  }
173 
181  template<typename T>
183  {
184  public:
185 
186  SharedValue(const T value = T())
187  : memory(new ControlBlock())
188  , handle(memory->handle())
189  {
190 
191  }
192 
196  SharedValue<T>& operator = (const T& value)
197  {
198  *getPtr() = value;
199  return *this;
200  }
201 
205  operator T ()
206  {
207  return *getPtr();
208  }
209 
215  detail::ControlBlockBase::Handle createHandle()
216  {
217  return memory->handle();
218  }
219 
224  T* getPtr()
225  {
226  return &memory->value;
227  }
228 
232  const char* getTypeDesignator()
233  {
234  return detail::fmt_type_traits<T>::designator();
235  }
236 
237  private:
238 
239  class ControlBlock : public detail::ControlBlockBase
240  {
241  public:
242  T value;
243  };
244 
245  ControlBlock* memory;
246  detail::ControlBlockBase::Handle handle;
247  };
248 
255  class Label : public UIObject
256  {
257  public:
258 
273  template<typename... Args>
274  Label(const std::string& name, const std::string_view fmt, Args&... args)
275  {
276  values = { args.createHandle()... };
277  const char* types[] = { args.getTypeDesignator()... };
278 
279  std::string temp;
280  auto numTypes = std::extent<decltype(types)>::value;
281  temp.reserve(fmt.size() + numTypes);
282 
283  for (std::size_t i = 0, c = 0; i < fmt.size(); ++i)
284  {
285  temp += fmt[i];
286 
287  if (fmt[i] == '%')
288  {
289  if (i + 1 < fmt.size() && fmt[i + 1] == '%')
290  {
291  continue;
292  }
293  else if (c < numTypes)
294  {
295  temp += types[c++];
296  }
297  else
298  {
299  abort("Invalid format specifier + argument list combination");
300  }
301  }
302 
303  }
304 
305  id = getInterface().createLabel(&getInterface(), name.c_str(), temp.c_str(), args.getPtr()...);
306  }
307 
309  {
310  getInterface().destroyResource(&getInterface(), id, 0);
311  }
312 
313  private:
314 
315  int id;
316  std::vector<detail::ControlBlockBase::Handle> values;
317  };
318 
319 }
320 #endif
ape::getInterface
APE_SharedInterface & getInterface()
Acquire the low-level C API.
ape::SharedValue
An assignable (from T ) value to be used as arguments for a Label. You should store these separately,...
Definition: label.h:182
ape::Label::Label
Label(const std::string &name, const std::string_view fmt, Args &... args)
Construct a label.
Definition: label.h:274
ape::Label::~Label
~Label()
Definition: label.h:308
ape::UIObject
Base traits class for all classes that are displayed in the GUI.
Definition: baselib.h:62
ape::SharedValue::SharedValue
SharedValue(const T value=T())
Definition: label.h:186
ape::Label
A Label is a printf-like format string displayed to the user, that is automatically updated in the GU...
Definition: label.h:255
abort
void abort(const char *reason)
Terminate the script (not the host application!) safely, with a reason. All resources will automatica...
ape
Definition: audiofile.h:7
ape::SharedValue::getPtr
T * getPtr()
Retrieve a pointer to the shared value. Used internally.
Definition: label.h:224
ape::SharedValue::getTypeDesignator
const char * getTypeDesignator()
Used internally.
Definition: label.h:232
baselib.h
ape::SharedValue::createHandle
detail::ControlBlockBase::Handle createHandle()
Create a handle to this value. The value will be kept alive until all the handles go out of scope.
Definition: label.h:215
ape::SharedValue::operator=
SharedValue< T > & operator=(const T &value)
Write to the value contained.
Definition: label.h:196