MT Showcase SDK
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
SchemaAttribute.hpp
1 #pragma once
2 
3 #include <QVariant>
4 #include <unordered_map>
5 #include <memory>
6 
7 #include "Hashes.hpp"
8 #include "Export.hpp"
9 
10 namespace Showcase
11 {
12 
13  class SchemaAttribute;
14 
16  class SchemaAttributeFloat;
17  class SchemaAttributeInt;
18  class SchemaAttributeString;
19  class SchemaAttributeComponent;
20  class SchemaAttributeDefault;
21  //class SchemaAttributeColor;
22  //class SchemaAttributeVector2f;
23  //class SchemaAttributeFile;
24 
25  typedef std::unordered_map<QByteArray, std::shared_ptr<SchemaAttribute>> SchemaAttributeMap;
26 
27  // --------------------------------------------------------------------------
28 
29  template <typename T>
30  struct Range
31  {
32  Range();
33  Range(T mi, T ma);
34  Range(bool boundedBelow, bool boundedAbove, T val);
35 
36  bool inside(T val) const;
37 
38  void setMin(T val);
39  void setMax(T val);
40 
41  static Range<T> parseRange(const QVariantMap& map);
42 
43  // Order is based on lexicographical order of the range limits.
44  // For example: [-1, -0.9] < [-0.999, Inf)
45  bool operator==(const Range<T>& other) const;
46  bool operator<(const Range<T>& other) const;
47 
48  T min;
49  T max;
50  bool isBoundedBelow;
51  bool isBoundedAbove;
52  };
53 
54  // --------------------------------------------------------------------------
55 
57  class SHOWCASE_API SchemaAttribute
58  {
59  public:
61  virtual ~SchemaAttribute();
62 
63  void setAttributeName(const QByteArray& name);
64  const QByteArray& attributeName() const;
65 
66  void setDescription(const QString& descr);
67  const QString& description() const;
68 
69  virtual QString type() const = 0;
70 
71  virtual void parseAttributes(const QVariantMap& map);
72 
73  static std::shared_ptr<SchemaAttribute> parse(const QVariantMap& map);
74 
75  protected:
76  QByteArray m_attributeName;
77  QString m_description;
78 
86  };
87  typedef std::shared_ptr<SchemaAttribute> SchemaAttributePtr;
88 
89  // --------------------------------------------------------------------------
90 
91  template <typename T>
92  class SchemaAttributeT : public SchemaAttribute
93  {
94  public:
95  SchemaAttributeT() {}
96  virtual ~SchemaAttributeT() {}
97 
98  void setDefaultValue(const T& value);
99  const T& valueRef() const;
100  T value() const;
101 
102  bool hasDefaultValue() const;
103 
104  virtual void parseAttributes(const QVariantMap& map) override;
105 
106  protected:
107  T m_defaultValue;
108  bool m_hasDefault;
109  };
110 
111  // --------------------------------------------------------------------------
112 
113  template <typename Numeric>
114  class SchemaAttributeNumericT : public SchemaAttributeT<Numeric>
115  {
116  public:
117  SchemaAttributeNumericT() {}
118  virtual ~SchemaAttributeNumericT() {}
119 
120  Range<Numeric> range() const;
121  void setRange(Range<Numeric> range);
122 
123  virtual void parseAttributes(const QVariantMap& map);
124 
125  private:
126  Range<Numeric> m_range;
127  };
128 
129  // --------------------------------------------------------------------------
130 
131  class SchemaAttributeFloat : public SchemaAttributeNumericT<float>
132  {
133  public:
134  SchemaAttributeFloat();
135  virtual ~SchemaAttributeFloat();
136 
137  virtual QString type() const override;
138  };
139 
140  class SchemaAttributeInt : public SchemaAttributeNumericT<int>
141  {
142  public:
143  SchemaAttributeInt();
144  virtual ~SchemaAttributeInt();
145 
146  virtual QString type() const override;
147  };
148 
149  class SchemaAttributeString : public SchemaAttributeT<QString>
150  {
151  public:
152  SchemaAttributeString();
153  virtual ~SchemaAttributeString();
154 
155  virtual QString type() const override;
156  };
157 
158  class SchemaAttributeComponent : public SchemaAttributeT<QString>
159  {
160  typedef std::map<QByteArray, Range<unsigned> > SlotRanges;
163 
164  public:
165  SchemaAttributeComponent();
166  virtual ~SchemaAttributeComponent();
167 
168  virtual QString type() const override;
169 
170  const QString& componentRole() const;
171  Range<unsigned> range() const;
172  Range<unsigned> range(const QByteArray & keyword) const;
173  const SlotRanges & allRanges() const;
174 
175  virtual void parseAttributes(const QVariantMap& map) override;
176 
177  private:
178  QString m_slotName;
179  SlotRanges m_range;
180  Range<unsigned> m_defaultRange;
181  };
182 
183  class SchemaAttributeDefault : public SchemaAttributeT<QString>
184  {
185  public:
186  SchemaAttributeDefault(const QString & type);
187  virtual ~SchemaAttributeDefault();
188 
189  virtual QString type() const override;
190 
191  private:
192  QString m_type;
193  };
194 
195  // --------------------------------------------------------------------------
196 
197  template <typename T>
198  void SchemaAttributeT<T>::setDefaultValue(const T &value)
199  {
200  m_defaultValue = value;
201  m_hasDefault = true;
202  }
203 
204  template <typename T>
205  const T& SchemaAttributeT<T>::valueRef() const
206  {
207  return m_defaultValue;
208  }
209 
210  template <typename T>
211  T SchemaAttributeT<T>::value() const
212  {
213  return m_defaultValue;
214  }
215 
216  template <typename T>
217  bool SchemaAttributeT<T>::hasDefaultValue() const
218  {
219  return m_hasDefault;
220  }
221 
222  template <typename T>
223  void SchemaAttributeT<T>::parseAttributes(const QVariantMap &map)
224  {
225  SchemaAttribute::parseAttributes(map);
226  auto it = map.find("default");
227  if(it != map.end()) {
228  setDefaultValue(it.value().value<T>());
229  }
230  }
231 
232  // --------------------------------------------------------------------------
233 
234  template <typename T>
235  Range<T> SchemaAttributeNumericT<T>::range() const
236  {
237  return m_range;
238  }
239 
240  template <typename T>
241  void SchemaAttributeNumericT<T>::setRange(Range<T> range)
242  {
243  m_range = range;
244  }
245 
246  template <typename T>
247  void SchemaAttributeNumericT<T>::parseAttributes(const QVariantMap &map)
248  {
249  SchemaAttributeT<T>::parseAttributes(map);
250  setRange(Range<T>::parseRange(map));
251  }
252 
253  // --------------------------------------------------------------------------
254 
255  template <typename T>
256  Range<T>::Range()
257  : isBoundedBelow(false),
258  isBoundedAbove(false)
259  {}
260 
261  template <typename T>
262  Range<T>::Range(T pmin, T pmax)
263  : min(pmin), max(pmax),
264  isBoundedBelow(true),
265  isBoundedAbove(true)
266  {}
267 
268  template <typename T>
269  Range<T>::Range(bool boundedBelow, bool boundedAbove, T val)
270  : isBoundedBelow(boundedBelow),
271  isBoundedAbove(boundedAbove)
272  {
273  if(boundedAbove && boundedBelow)
274  min = max = val;
275  else if(boundedAbove)
276  max = val;
277  else if(boundedBelow)
278  min = val;
279  }
280 
281  template <typename T>
282  bool Range<T>::inside(T val) const
283  {
284  if(!isBoundedAbove && !isBoundedBelow) {
285  return true;
286  } else if(!isBoundedAbove) {
287  return val >= min;
288  } else if(!isBoundedBelow) {
289  return val <= max;
290  } else {
291  return val <= max && val >= min;
292  }
293  }
294 
295  template <typename T>
296  bool Range<T>::operator==(const Range<T>& other) const
297  {
298  return !(*this < other) && !(other < *this);
299  }
300 
301  template <typename T>
302  bool Range<T>::operator<(const Range<T>& other) const
303  {
304  return std::make_tuple(isBoundedBelow, min, !isBoundedAbove, max)
305  < std::make_tuple(other.isBoundedBelow, other.min, !other.isBoundedAbove, other.max);
306  }
307 
308  template <typename T>
309  void Range<T>::setMin(T val)
310  {
311  min = val;
312  isBoundedBelow = true;
313  }
314 
315  template <typename T>
316  void Range<T>::setMax(T val)
317  {
318  max = val;
319  isBoundedAbove = true;
320  }
321 
322  template <typename T>
323  Range<T> Range<T>::parseRange(const QVariantMap& map)
324  {
325  Range<T> ran;
326  auto it = map.find("min");
327  if(it != map.end()) {
328  ran.setMin(it.value().value<T>());
329  }
330 
331  it = map.find("max");
332  if(it != map.end()) {
333  ran.setMax(it.value().value<T>());
334  }
335 
336  return ran;
337  }
338 
339 }