ImGraph
 All Classes Functions Variables Enumerations Pages
ParamValue.h
1 #ifndef _BLOCK_PARAM__valueHEADER_
2 #define _BLOCK_PARAM__valueHEADER_
3 
4 #ifdef _WIN32
5 #pragma warning(push)
6 #pragma warning(disable:4996 4251 4275 4800 4503 4190)
7 #endif
8 #include <boost/variant.hpp>
9 #include <opencv2/core/core.hpp>
10 #include <boost/thread/recursive_mutex.hpp>
11 #include <boost/thread/condition_variable.hpp>
12 
13 #include <set>
14 #include <QWidget>
15 #include <QString>
16 #ifdef _WIN32
17 #pragma warning(pop)
18 #endif
19 
20 namespace charliesoft
21 {
22  class ParamValue;
23  class ParamValidator;
24  class Block;
25  struct BlockLink;
26  struct ParamDefinition;
27 
28  enum ParamType
29  {
30  Boolean = 0, Int, Float, Color, Matrix, String, FilePath, ListBox, AnyType, typeError
31  };
32 
33  struct Not_A_Value
34  {
35  bool justForMe_;
36  bool operator == (const Not_A_Value &b) const
37  {
38  return false;
39  }
40  };
41 
42  typedef boost::variant <
43  bool,
44  int,
45  double,
46  std::string,
47  cv::Scalar,
48  cv::Mat,
49  ParamValue*,
50  Not_A_Value > VariantClasses;
51 
52  class ParamValue : public QObject
53  {
54  Q_OBJECT;
55 
56  mutable boost::recursive_mutex _mtx; //< explicit mutex declaration
57  boost::condition_variable _cond_sync; //< global sync condition
58  mutable bool _newValue; //< is this value not yet processed?
59  std::vector<ParamValidator*> _validators;
60  std::set<ParamValue*> _distantListeners;
61  Block *_block;
62  ParamDefinition* _definition;
63  std::string _name;
64  bool _isOutput;
65  bool _paramNeeded;
66 
67  VariantClasses _value;
68 
69  void notifyUpdate(bool isNew);
70  void notifyRemove();
71  public:
72  ParamValue(Block *algo, std::string name, bool isOutput) :
73  _block(algo), _name(name), _isOutput(isOutput), _value(Not_A_Value()){
74  _newValue = false; _paramNeeded = true; _definition = NULL;
75  };
76  ParamValue() :
77  _block(NULL), _name(""), _isOutput(false), _value(Not_A_Value()){
78  _newValue = false; _paramNeeded = true; _definition = NULL;
79  };
80  ParamValue(Block *algo, ParamDefinition* def, bool isOutput);
81  ParamValue(bool v) : ParamValue(){
82  _value = v;
83  };
84  ParamValue(int v) :ParamValue(){
85  _value = v;
86  };
87  ParamValue(double v) :ParamValue(){
88  _value = v;
89  };
90  ParamValue(const char* v) :ParamValue(std::string(v)){
91  };
92  ParamValue(std::string v) :ParamValue(){
93  _value = v;
94  };
95  ParamValue(cv::Scalar v) :ParamValue(){
96  _value = v;
97  };
98  ParamValue(cv::Mat v) :ParamValue(){
99  _value = v;
100  };
102  };
104  _value = v;
105  if (v != NULL) v->_distantListeners.insert(this);
106  };
107  ParamValue(const ParamValue& va) :
108  _block(va._block), _name(va._name), _isOutput(va._isOutput), _value(va._value),
109  _validators(va._validators), _distantListeners(va._distantListeners){
110  _newValue = false; _paramNeeded = true; _definition = va._definition;
111  };
112 
113  ~ParamValue();
114 
115  const std::set<ParamValue*>& getListeners() const { return _distantListeners; };
116  std::set<ParamValue*>& getListeners() { return _distantListeners; };
117 
118  static ParamValue fromString(ParamType,std::string);
119 
120  ParamValue& operator=(bool const &rhs);
121  ParamValue& operator=(int const &rhs);
122  ParamValue& operator=(double const &rhs);
123  ParamValue& operator=(const char* rhs);
124  ParamValue& operator=(std::string const &rhs);
125  ParamValue& operator=(cv::Scalar const &rhs);
126  ParamValue& operator=(cv::Mat const &rhs);
127  ParamValue& operator=(Not_A_Value const &rhs);
128  ParamValue& operator=(ParamValue const &rhs);
129  ParamValue& operator=(ParamValue* rhs);
130  bool operator== (const ParamValue &b) const;
131  bool operator< (const ParamValue &b) const;
132  bool operator> (const ParamValue &b) const;
133  bool operator<= (const ParamValue &b) const
134  {
135  return this->operator==(b) || this->operator<(b);
136  }
137  bool operator>= (const ParamValue &b) const
138  {
139  return this->operator==(b) || this->operator>(b);
140  }
141  bool operator!= (const ParamValue &b) const
142  {
143  return !(this->operator==(b));
144  }
145 
147  void update();
148 
149  bool isNeeded(){ return _paramNeeded; };
150  void isNeeded(bool paramNeeded){ _paramNeeded = paramNeeded; };
151 
152  std::string toString() const;
153  BlockLink toBlockLink() const;
154 
155  void validate(const ParamValue& other) const;
156  void addValidator(std::initializer_list<ParamValidator*> list);
157  template <class T>
158  bool containValidator() const
159  {
160  for (auto& val : _validators)
161  {
162  if (dynamic_cast<T*>(val) != NULL)
163  return true;
164  }
165  return false;
166  };
167 
168  std::string getName() const { return _name; };
169  ParamDefinition* getDefinition() const { return _definition; }
170  void setName(std::string val) { _name = val; }
171 
172  bool isNew() const
173  {
174  return _newValue;
175  }
176  void setNew(bool isNew){ _newValue = isNew; };
177  bool isDefaultValue() const;
178  void setDefaultValue();
179  bool isLinked() const {
180  boost::unique_lock<boost::recursive_mutex> lock(_mtx);
181  return (_value.type() == typeid(ParamValue*)) &&
182  boost::get<ParamValue*>(_value) != NULL;
183  };
184 
185  ParamType getType(bool allow_AnyType = true) const;
186  Block * getBlock() const { return _block; };
187  void setBlock(Block *b) { _block=b; };
188 
189  std::string getValFromList();
190 
191  template<typename T>
192  T get() const
193  {
194  boost::unique_lock<boost::recursive_mutex> lock(_mtx);
195  if (isLinked())
196  {
197  if (typeid(T) == typeid(ParamValue*))
198  return boost::get<T>(_value);
199  return boost::get<ParamValue*>(_value)->get<T>();
200  }
201  if (_value.type() == typeid(Not_A_Value))
202  {
203  return T();
204  }
205  try
206  {
207  return boost::get<T>(_value);
208  }
209  catch (boost::bad_get&)
210  {
211  return T();
212  }
213  }
214 
215  template<>
216  int get<int>() const
217  {
218  boost::unique_lock<boost::recursive_mutex> lock(_mtx);
219  if (isLinked())
220  return boost::get<ParamValue*>(_value)->get<int>();
221 
222  if (_value.type() == typeid(Not_A_Value))
223  {
224  return 0;
225  }
226  try
227  {
228  return boost::get<int>(_value);
229  }
230  catch (boost::bad_get&)
231  {
232  try
233  {
234  return static_cast<int>(boost::get<double>(_value));
235  }
236  catch (boost::bad_get&)
237  {
238  return 0;
239  }
240  }
241  }
242 
243  template<>
244  double get<double>() const
245  {
246  boost::unique_lock<boost::recursive_mutex> lock(_mtx);
247  if (isLinked())
248  return boost::get<ParamValue*>(_value)->get<double>();
249 
250  if (_value.type() == typeid(Not_A_Value))
251  {
252  return 0.;
253  }
254  try
255  {
256  return boost::get<double>(_value);
257  }
258  catch (boost::bad_get&)
259  {
260  try
261  {
262  return static_cast<double>(boost::get<int>(_value));
263  }
264  catch (boost::bad_get&)
265  {
266  return 0.;
267  }
268  }
269  }
270 
271  template<>
272  float get<float>() const
273  {
274  return static_cast<float>(get<double>());
275  }
276 
277  void setValue(const ParamValue* value)
278  {
279  boost::unique_lock<boost::recursive_mutex> lock(_mtx);
280  notifyRemove();
281  _newValue = true;
282  if (value->isLinked())
283  value = value->get<ParamValue*>();
284  switch (value->getType())
285  {
286  case Boolean:
287  _value = value->get<bool>();
288  break;
289  case Int:
290  _value = value->get<int>();
291  break;
292  case Float:
293  _value = value->get<double>();
294  break;
295  case String:
296  case FilePath:
297  _value = value->get<std::string>();
298  break;
299  case Color:
300  _value = value->get<cv::Scalar>();
301  break;
302  default:
303  _value = value->get<cv::Mat>();
304  break;
305  }
306  notifyUpdate(_newValue);
307  }
308 
309  void valid_and_set(const ParamValue& v);
310 
311  Q_SIGNAL void paramUpdated();
312  };
313 }
314 
315 #endif
Definition: Block.h:163
void update()
Update the value. This will render the corresponding block and every ancestors.
Definition: ParamValue.cpp:178
Definition: ParamValue.h:33
Definition: Block.h:197
Definition: ParamValue.h:52