synfig-core  1.0.3
value.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
23 /* ========================================================================= */
24 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __SYNFIG_VALUE_H
28 #define __SYNFIG_VALUE_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 #include "base_types.h"
33 
34 // TODO: remove following includes
35 #include "angle.h"
36 #include "segment.h"
37 #include "string.h"
38 #include <list>
39 #include <vector>
40 #include <ETL/trivial>
41 #include <ETL/handle>
42 #include "general.h"
43 #include "blinepoint.h"
44 #include "bone.h"
45 #include "widthpoint.h"
46 #include "dashitem.h"
47 #include "exception.h"
48 #include "interpolation.h"
49 #include "transformation.h"
50 
51 #ifdef USE_HALF_TYPE
52 #include <OpenEXR/half.h>
53 #endif
54 
55 #include <ETL/ref_count>
56 
57 /* === M A C R O S ========================================================= */
58 
59 /* === T Y P E D E F S ===================================================== */
60 
61 /* === C L A S S E S & S T R U C T S ======================================= */
62 
63 namespace synfig {
64 
65 // TODO: remove following predeclarations
66 class Canvas;
67 class Vector;
68 class Time;
69 struct Segment;
70 class Gradient;
71 class BLinePoint;
72 class WidthPoint;
73 class DashItem;
74 class Color;
75 class Bone;
76 class ValueNode_Bone;
77 class Matrix;
78 class BoneWeightPair;
79 
83 class ValueBase
84 {
85  /*
86  -- ** -- T Y P E S -----------------------------------------------------------
87  */
88 
89 public:
90  typedef std::vector<ValueBase> List;
91 
92  /*
93  -- ** -- D A T A -------------------------------------------------------------
94  */
95 
96 protected:
100  void *data;
104  etl::reference_counter ref_count;
106  bool loop_;
108  bool static_;
111 
112  /*
113  -- ** -- C O N S T R U C T O R S -----------------------------------
114  */
115 
116 public:
117 
119  ValueBase();
120 
122  template <typename T>
123  ValueBase(const T &x, bool loop_=false, bool static_=false):
126  {
127 #ifdef INITIALIZE_TYPE_BEFORE_USE
128  type->initialize();
129 #endif
130  set(x);
131  }
132 
133  template <typename T>
134  ValueBase(const std::vector<T> &x, bool loop_=false, bool static_=false):
137  {
138 #ifdef INITIALIZE_TYPE_BEFORE_USE
139  type->initialize();
140 #endif
141  set_list_of(x);
142  }
143 
145  ValueBase(Type &x);
146 
148  ~ValueBase();
149 
150  /*
151  -- ** -- O P E R A T O R S ---------------------------------------------------
152  */
153 
154 public:
155 
158  template <class T> ValueBase& operator=(const T& x)
159  { set(x); return *this; }
160 
162  ValueBase& operator=(const ValueBase& x);
163 
165  bool operator==(const ValueBase& rhs)const;
166 
168  bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); }
169 
171  const ValueBase &operator[](int index)const
172  { assert(type==&type_list); assert(index>0); return get_list()[index]; }
173 
174  /*
175  -- ** -- M E M B E R F U N C T I O N S -------------------------------------
176  */
177 
178 public:
179 
181  void clear();
182 
184  bool get_loop()const { return loop_; }
185 
187  void set_loop(bool x) { loop_=x; }
188 
190  bool get_static()const { return static_; }
191 
193  void set_static(bool x) { static_=x; }
194 
197 
200 
202  void copy(const ValueBase& x);
203 
205  void copy_properties_of(const ValueBase& x);
206 
208  bool empty()const;
209 
211  Type& get_contained_type()const;
212 
214  bool is_valid()const;
215 
217  String type_name()const { return type->description.name; }
218 
220  Type& get_type()const { return *type; }
221 
222  template<typename T>
223  inline static bool can_get(const TypeId type, const T &x)
224  { return _can_get(type, types_namespace::get_type_alias(x)); }
225  template<typename T>
226  inline static bool can_get(const Type& type, const T &x) { return can_get(type.identifier, x); }
227  template<typename T>
228  inline static bool can_set(const TypeId type, const T &x)
229  { return _can_set(type, types_namespace::get_type_alias(x)); }
230  template<typename T>
231  inline static bool can_set(const Type& type, const T &x) { return can_set(type.identifier, x); }
232  template<typename T>
233  inline static bool can_put(const TypeId type, const T &x)
234  { return _can_put(type, types_namespace::get_type_alias(x)); }
235  template<typename T>
236  inline static bool can_put(const Type& type, const T &x) { return can_put(type.identifier, x); }
237  inline static bool can_copy(const TypeId dest, const TypeId src)
238  { return NULL != Type::get_operation<Operation::CopyFunc>(Operation::Description::get_copy(dest, src)); }
239  inline static bool can_copy(const Type& dest, const Type& src) { return can_copy(dest.identifier, src.identifier); }
240 
241  template<typename T> inline bool can_get(const T &x) const { return is_valid() && can_get(*type, x); }
242  template<typename T> inline bool can_set(const T &x) const { return can_set(*type, x); }
243  template<typename T> inline bool can_put(const T &x) const { return is_valid() && can_put(*type, x); }
244  bool can_copy_from(const TypeId type) const { return can_copy(this->type->identifier, type); }
245  bool can_copy_from(const Type& type) const { return can_copy(*this->type, type); }
246  bool can_copy_to(const TypeId type) const { return can_copy(type, this->type->identifier); }
247  bool can_copy_to(const Type& type) const { return can_copy(type, *this->type); }
248 
249  template<typename T> bool same_type_as(const T&x) const { return can_get(x) && can_set(x) && can_put(x); }
250 
251  // === GET MEMBERS ========================================================
253  template <typename T>
254  inline const T &get(const T &x)const { return (const T&)_get(types_namespace::get_type_alias(x)); }
255 
257  const List& get_list()const { return get(List()); }
258 
259  template<typename T>
260  std::vector<T> get_list_of(const T &x)const
261  {
262  const List &list = get_list();
263  std::vector<T> out_list;
264  out_list.reserve(list.size());
265  for(List::const_iterator i = list.begin(); i != list.end(); ++i)
266  if (i->can_get(x))
267  out_list.push_back(i->get(x));
268  return out_list;
269  }
270 
271  template<typename T>
272  void set_list_of(const std::vector<T> &list)
273  {
274  *this = List(list.begin(), list.end());
275  }
276 
277 #ifdef _DEBUG
278  String get_string() const;
279 #endif // _DEBUG
280  // ========================================================================
281 
283  template <typename T>
284  inline void put(T* x)const { _put(types_namespace::get_type_alias(*x), x); }
285 
287  template <typename T>
288  inline void set(const T& x) { _set(x); }
289 
290 
291  /*
292  -- ** -- S T A T I C F U N C T I O N S -------------------------------------
293  */
294 
295 public:
299  static Type& ident_type(const String &str);
300 
301 
302  // === GET TYPE MEMBERS ===================================================
303  template<typename T>
304  static Type& get_type(const T&) { return Type::get_type<T>(); }
305 
306  // TODO: remove this, when removed all references in code
307  static Type& get_type(const List &)
308  { return Type::get_type<List>(); }
309  static Type& get_type(Canvas* const &)
310  { return Type::get_type<Canvas*>(); }
311  static Type& get_type(ValueNode_Bone* const &)
312  { return Type::get_type<ValueNode_Bone*>(); }
313  template <typename T> static Type& get_type(const T* &)
314  { int i[(int)1 - (int)sizeof(T)]; return type_nil; }
315  template <typename T> static Type& get_type(const std::vector<T> &)
316  { int i[(int)1 - (int)sizeof(T)]; return type_nil; }
317  template <typename T> static Type& get_type(const std::list<T> &)
318  { int i[(int)1 - (int)sizeof(T)]; return type_nil; }
319  // ========================================================================
320 
321 
322  /*
323  -- ** -- C A S T O P E R A T O R S -----------------------------------------
324  */
325 
326 public:
328  /*
329  template<typename T>
330  operator const T&() const
331  {
332  Type &t = Type::get_type<T>();
333  Operation::GenericFuncs<T>::GetFunc func =
334  Type::get_operation<Operation::GenericFuncs<T>::GetFunc>(
335  Operation::Description::get_get(t.identifier) );
336  assert(func != NULL);
337  return func(data);
338  }
339  */
340 
341  /*
342  -- ** -- O T H E R -----------------------------------------------------------
343  */
344 
345 private:
346  void create(Type &type);
347  inline void create() { create(*type); }
348 
349  template <typename T>
350  inline static bool _can_get(const TypeId type, const T &)
351  {
352  typedef typename T::AliasedType TT;
353  return NULL !=
354  Type::get_operation<typename Operation::GenericFuncs<TT>::GetFunc>(
356  }
357 
358  template <typename T>
359  inline static bool _can_put(const TypeId type, const T &)
360  {
361  typedef typename T::AliasedType TT;
362  return NULL !=
363  Type::get_operation<typename Operation::GenericFuncs<TT>::PutFunc>(
365  }
366 
367  template <typename T>
368  inline static bool _can_set(const TypeId type, const T &)
369  {
370  typedef typename T::AliasedType TT;
371  return NULL !=
372  Type::get_operation<typename Operation::GenericFuncs<TT>::SetFunc>(
374  }
375 
376  template <typename T>
377  const typename T::AliasedType& _get(const T &)const
378  {
379  typedef typename T::AliasedType TT;
380 #ifdef _DEBUG
381  if (!is_valid())
382  printf("%s:%d !is_valid()\n", __FILE__, __LINE__);
383 #endif
384  assert(is_valid());
385  typename Operation::GenericFuncs<TT>::GetFunc func =
386  Type::get_operation<typename Operation::GenericFuncs<TT>::GetFunc>(
388 #ifdef _DEBUG
389  if (func == NULL)
390  printf("%s:%d %s get_func == NULL\n", __FILE__, __LINE__, type->description.name.c_str());
391 #endif
392  assert(func != NULL);
393  return func(data);
394  }
395 
396  template <typename T>
397  void _put(const T &, typename T::AliasedType *x)const
398  {
399  assert(is_valid());
400  typedef typename T::AliasedType TT;
401  typename Operation::GenericFuncs<TT>::PutFunc func =
402  Type::get_operation<typename Operation::GenericFuncs<TT>::PutFunc>(
404  assert(func != NULL);
405  func(*x, data);
406  }
407 
408  template<typename T>
409  void __set(const T &alias, const typename T::AliasedType &x)
410  {
411  typedef typename T::AliasedType TT;
412 #ifdef INITIALIZE_TYPE_BEFORE_USE
413  alias.type.initialize();
414 #endif
415 
416  Type &current_type = *type;
417  if (current_type != type_nil)
418  {
419  typename Operation::GenericFuncs<TT>::SetFunc func =
420  Type::get_operation<typename Operation::GenericFuncs<TT>::SetFunc>(
421  Operation::Description::get_set(current_type.identifier) );
422  if (func != NULL)
423  {
424  if (!ref_count.unique()) create(current_type);
425  func(data, x);
426  return;
427  }
428  }
429 
430  Type &new_type = alias.type;
431  assert(new_type != current_type);
432  assert(new_type != type_nil);
433 
434  typename Operation::GenericFuncs<TT>::SetFunc func =
435  Type::get_operation<typename Operation::GenericFuncs<TT>::SetFunc>(
436  Operation::Description::get_set(new_type.identifier) );
437  assert(func != NULL);
438 
439  create(new_type);
440  assert(*type != type_nil);
441  func(data, x);
442  }
443 
445  template <typename T>
446  inline void _set(const T& x) { __set(types_namespace::get_type_alias(x), x); }
447 
448 }; // END of class ValueBase
449 
450 
454 template <class T>
455 class Value : public ValueBase
456 {
457 public:
458  Value(const T &x):ValueBase(x) { }
459  Value(const ValueBase &x):ValueBase(x) { }
460  T get()const { return ValueBase::get(T()); }
461  void put(T* x)const { ValueBase::put(x); }
462  void set(const T& x) { ValueBase::operator=(x); }
463  Value<T>& operator=(const T& x) { set(x); return *this; }
466 
467 }; // END of class Value
468 
469 }; // END of namespace synfig
470 
471 /* === E N D =============================================================== */
472 
473 #endif