Merge branch 'genete_static_values'
[synfig.git] / synfig-core / src / synfig / value.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file value.h
3 **      \brief Template Header
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **      Copyright (c) 2007, 2008 Chris Moore
10 **
11 **      This package is free software; you can redistribute it and/or
12 **      modify it under the terms of the GNU General Public License as
13 **      published by the Free Software Foundation; either version 2 of
14 **      the License, or (at your option) any later version.
15 **
16 **      This package is distributed in the hope that it will be useful,
17 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 **      General Public License for more details.
20 **      \endlegal
21 */
22 /* ========================================================================= */
23
24 /* === S T A R T =========================================================== */
25
26 #ifndef __SYNFIG_VALUE_H
27 #define __SYNFIG_VALUE_H
28
29 /* === H E A D E R S ======================================================= */
30
31 #include "angle.h"
32 #include "segment.h"
33 #include "string.h"
34 #include <list>
35 #include <vector>
36 #include <ETL/trivial>
37 #include <ETL/handle>
38 #include "general.h"
39 #include "blinepoint.h"
40 #include "exception.h"
41
42 #ifdef USE_HALF_TYPE
43 #include <OpenEXR/half.h>
44 #endif
45
46
47 #include <ETL/ref_count>
48
49 /* === M A C R O S ========================================================= */
50
51 /* === T Y P E D E F S ===================================================== */
52
53 /* === C L A S S E S & S T R U C T S ======================================= */
54
55 namespace synfig {
56
57 class Canvas;
58 class Vector;
59 class Time;
60 class Segment;
61 class Gradient;
62 class BLinePoint;
63 class Color;
64
65 /*!     \class ValueBase
66 **      \brief Base class for the Values of Synfig
67 */
68 class ValueBase
69 {
70         /*
71  --     ** -- T Y P E S -----------------------------------------------------------
72         */
73
74 public:
75
76         //! This enum lists all the types of values
77         enum Type
78         {
79                 TYPE_NIL=0,                     //!< Represents an empty value
80
81                 TYPE_BOOL,                      //!< Boolean value (1 or 0)
82                 TYPE_INTEGER,           //!< Integer value -1, 0, 1, etc.
83                 TYPE_ANGLE,                     //!< Angle value (Real number internally)
84
85                 // All types after this point are larger than 32 bits
86
87                 TYPE_TIME,                      //!< Time value
88                 TYPE_REAL,                      //!< Real value (floating point number)
89
90                 // All types after this point are larger than 64 bits
91
92                 TYPE_VECTOR,            //!< Vector value (Real, Real) Points are Vectors too
93                 TYPE_COLOR,                     //!< Color (Real, Real, Real, Real)
94                 TYPE_SEGMENT,           //!< Segment Point and Vector
95                 TYPE_BLINEPOINT,        //!< BLinePoint Origin (Point) 2xTangents (Vector) Width (Real), Origin (Real) Split Tangent (Boolean)
96
97                 // All types after this point require construction/destruction
98
99                 TYPE_LIST,                      //!< List of any of above
100                 TYPE_CANVAS,            //!< Canvas
101                 TYPE_STRING,            //!< String
102                 TYPE_GRADIENT,          //!< Color Gradient
103
104                 TYPE_END                        //!< Not a valid type, used for sanity checks
105         };
106
107 private:
108
109         typedef std::vector<ValueBase> list_type;
110
111         /*
112  --     ** -- D A T A -------------------------------------------------------------
113         */
114
115 protected:
116         //! The type of value
117         Type type;
118         //! Pointer to hold the data of the value
119         void *data;
120         //! Counter of Value Nodes that refers to this Value Base
121         //! Value base can only be destructed if the ref_count is not greater than 0
122         //!\see etl::reference_counter
123         etl::reference_counter ref_count;
124         //! For Values with loop option like TYPE_LIST
125         bool loop_;
126         //! For Values of Constant Value Nodes
127         bool static_;
128
129         /*
130  --     ** -- C O N S T R U C T O R S -----------------------------------
131         */
132
133 public:
134
135         //! Default constructor
136         ValueBase();
137
138         //! Template constructor for any type
139         template <typename T>
140         ValueBase(const T &x, bool loop_=false, bool static_=false):
141                 type(TYPE_NIL),data(0),ref_count(0),loop_(loop_), static_(static_)
142                 { set(x); }
143
144         //! Copy constructor. The data is not copied, just the type.
145         ValueBase(Type x);
146
147         //! Default destructor
148         ~ValueBase();
149
150         /*
151  --     ** -- O P E R A T O R S ---------------------------------------------------
152         */
153
154 public:
155
156         //! Template for the operator assignation operator for non ValueBase classes
157         //! \see set()
158         template <class T> ValueBase& operator=(const T& x)
159                 { set(x); return *this; }
160
161         //!Operator asignation for ValueBase classes. Does a exact copy of \x
162         ValueBase& operator=(const ValueBase& x);
163
164         //! Eqaul than operator. Segment, Gradient and Bline Points cannot be compared.
165         bool operator==(const ValueBase& rhs)const;
166
167         //! Not equal than operator.
168         bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); }
169
170         //!     Constant index operator for when value is of type TYPE_LIST
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
180         //! Deletes the data only if the ref count is zero
181         void clear();
182
183         //! Gets the loop option.
184         bool get_loop()const { return loop_; }
185
186         //! Sets the loop option.
187         void set_loop(bool x) { loop_=x; }
188
189         //! Gets the static option.
190         bool get_static()const { return static_; }
191
192         //! Sets the static option.
193         void set_static(bool x) { static_=x; }
194
195         //! True if the Value is not valid or is type LIST and is empty
196         bool empty()const;
197
198         //! Gets the contained type in the Value Base
199         Type get_contained_type()const;
200
201         //! Returns true if the contained value is defined and valid.
202         bool is_valid()const;
203
204         //!     Returns a string containing the name of the type. Used for sif files
205         String type_name()const { return type_name(type); }
206
207         //! Returns the type of the contained value
208         const Type & get_type()const { return type; }
209
210         //! Checks the type of the parameter against itself. Returns true if they are of the same type.
211         //! Template for any class
212         template <class T> bool
213         same_type_as(const T &x)const
214         {
215                 const Type testtype(get_type(x));
216
217                 return same_type_as(type, testtype);
218         }
219         //! Checks the type of the parameter against itself. Returns true if they are of the same type.
220         bool same_type_as(const Type testtype)const
221         {
222                 return same_type_as(type, testtype);
223         }
224
225         //! Compares two types.  Returns true if they are the same type.
226         static bool same_type_as(const Type type1, const Type type2)
227         {
228                 if (type1 == type2) return true;
229                 if ((type1 == TYPE_REAL || type1 == TYPE_TIME) &&
230                         (type2 == TYPE_REAL || type2 == TYPE_TIME))
231                         return true;
232                 return false;
233         }
234
235
236         // === GET MEMBERS ========================================================
237         //! Template to get the ValueBase class data by casting the type
238         template <typename T>
239         const T &get(const T& x __attribute__ ((unused)))const
240         {
241                 assert(is_valid() && same_type_as(x));
242                 return *static_cast<const T*>(data);
243         }
244         //! Gets the Real part of the data
245         float get(const float &)const { return get(Real()); }
246         //! Gets the Canvas Handle part of the data based on Canvas Handle type
247         etl::loose_handle<Canvas> get(const etl::handle<Canvas>&)const
248                 { return get(etl::loose_handle<Canvas>()); }
249         //! Gets the Canvas Handle part of the data based on Canvas pointer type
250         etl::loose_handle<Canvas> get(Canvas*)const
251                 { return get(etl::loose_handle<Canvas>()); }
252         //! Gets the data as char pointer based on char pointer
253         const char* get(const char*)const;
254         //! Gets the data as List Type
255         const list_type& get_list()const { return get(list_type()); }
256
257 #ifdef _DEBUG
258         String get_string() const;
259 #endif  // _DEBUG
260         // ========================================================================
261
262
263
264         // === PUT MEMBERS ========================================================
265         //! Put template for any class
266         template <typename T>
267         void put(T* x)const
268         {
269                 assert(same_type_as(*x));
270                 *x=*static_cast<const T*>(data);
271         }
272         //! Put for float values
273         void put(float* x)const { *x=get(Real()); }
274         //! Put for char values (Not defined??)
275         void put(char** x)const;
276         // ========================================================================
277
278
279
280         // === SET MEMBERS ========================================================
281         //! Set template for any class
282         template <typename T> void set(const T& x) { _set(x); }
283         //! Set for float
284         void set(const float &x) { _set(Real(x)); }
285         //! Set for List Type
286         void set(const list_type &x);
287         //! Set for char string
288         void set(const char* x);
289         //! Set for char string
290         void set(char* x);
291         //! Set for Canvas pointer
292         void set(Canvas*x);
293         //! Set for Canvas handle
294         void set(etl::loose_handle<Canvas> x);
295         //! Set for Canvas handle
296         void set(etl::handle<Canvas> x);
297         //! Set template for standar vector
298         template <class T> void set(const std::vector<T> &x)
299                 { _set(list_type(x.begin(),x.end())); }
300         //! Set template for standar list
301         template <class T> void set(const std::list<T> &x)
302                 { _set(list_type(x.begin(),x.end())); }
303         // ========================================================================
304
305
306         /*
307  --     ** -- S T A T I C   F U N C T I O N S -------------------------------------
308         */
309
310 public:
311
312         //!     Returns a string containing the name of the given Type
313         static String type_name(Type id);
314
315         //!     Returns a string containing the translated name of the given Type
316         static String type_local_name(Type id);
317
318         //!     Returns a the corresponding Type of the described type.
319         //! Notice that this is used in the loadcanvas. It should keep all
320         //! all type names used in previous sif files
321         static Type ident_type(const String &str);
322
323
324         // === GET TYPE MEMBERS ===================================================
325         static Type get_type(bool) { return TYPE_BOOL; }
326         static Type get_type(int) { return TYPE_INTEGER; }
327         static Type get_type(const Angle&) { return TYPE_ANGLE; }
328         static Type get_type(const Time&) { return TYPE_TIME; }
329         static Type get_type(const Real&) { return TYPE_REAL; }
330         static Type get_type(const float&) { return TYPE_REAL; }
331         static Type get_type(const Vector&) { return TYPE_VECTOR; }
332         static Type get_type(const Color&) { return TYPE_COLOR; }
333         static Type get_type(const Segment&) { return TYPE_SEGMENT; }
334         static Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; }
335         static Type get_type(const String&) { return TYPE_STRING; }
336         static Type get_type(const Gradient&) { return TYPE_GRADIENT; }
337         static Type get_type(Canvas*) { return TYPE_CANVAS; }
338         static Type get_type(const etl::handle<Canvas>&)
339                 { return TYPE_CANVAS; }
340         static Type get_type(const etl::loose_handle<Canvas>&)
341                 { return TYPE_CANVAS; }
342         static Type get_type(const list_type&) { return TYPE_LIST; }
343         template <class T> static Type get_type(const std::vector<T> &/*x*/)
344                 { return TYPE_LIST; }
345         template <class T> static Type get_type(const std::list<T> &/*x*/)
346                 { return TYPE_LIST; }
347         // ========================================================================
348
349
350         /*
351  --     ** -- C A S T   O P E R A T O R S -----------------------------------------
352         */
353
354 public:
355         //! I wonder why are those casting operators disabled...
356         operator const list_type&()const { return get_list(); }
357         operator const Angle&()const { return get(Angle()); }
358         //operator const Color&()const { return get(Color()); }
359         operator const Real&()const { return get(Real()); }
360         //operator const Time&()const { return get(Time()); }
361
362         operator const Vector&()const {  return get(Vector()); }
363         operator const BLinePoint&()const {  return get(BLinePoint()); }
364         //operator const int&()const {  return get(int()); }
365         //operator const String&()const {  return get(String()); }
366         //operator const char *()const {  return get(String()).c_str(); }
367         operator const Segment&()const { return get(Segment()); }
368
369
370         /*
371  --     ** -- O T H E R -----------------------------------------------------------
372         */
373
374 public:
375
376 #ifdef USE_HALF_TYPE
377         half get(const half &)const { return get(Real()); }
378         void put(half*x)const { *x=get(Real()); }
379         void set(const half &x) { _set(Real(x)); }
380         static Type get_type(const half&) { return TYPE_REAL; }
381         operator half()const { return get(Real()); }
382 #endif
383
384
385         //! Cast operator template to obtain the standard list from the TYPE LIST
386         template <class T>
387         operator std::list<T>()const
388         {
389                 assert(type==TYPE_LIST);
390                 std::list<T> ret(get_list().begin(),get_list().end());
391                 return ret;
392         }
393         //! Cast operator template to obtain the standard vector from the TYPE LIST
394         template <class T>
395         operator std::vector<T>()const
396         {
397                 assert(type==TYPE_LIST);
398                 std::vector<T> ret(get_list().begin(),get_list().end());
399                 return ret;
400         }
401
402
403 private:
404         //! Internal set template. Takes in consideration the reference counter
405         template <typename T> void
406         _set(const T& x)
407         {
408                 const Type newtype(get_type(x));
409
410                 assert(newtype!=TYPE_NIL);
411
412                 if(newtype==type)
413                 {
414                         if(ref_count.unique())
415                         {
416                                 *reinterpret_cast<T*>(data)=x;
417                                 return;
418                         }
419                 }
420
421                 clear();
422
423                 type=newtype;
424                 ref_count.reset();
425                 data=new T(x);
426         }
427
428 }; // END of class ValueBase
429
430
431 /*!     \class Value
432 **      \brief Template for all the valid Value Types
433 */
434 template <class T>
435 class Value : public ValueBase
436 {
437 public:
438         Value(const T &x):ValueBase(x)
439         {
440         }
441
442         Value(const ValueBase &x):ValueBase(x)
443         {
444                 if(!x.same_type_as(T()))
445                         throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
446         }
447
448         Value()
449         {
450         }
451
452         T get()const { return ValueBase::get(T()); }
453
454         void put(T* x)const     { ValueBase::put(x); }
455
456         void set(const T& x) { ValueBase::operator=(x); }
457
458         Value<T>& operator=(const T& x) { set(x); return *this; }
459
460         Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
461
462         Value<T>& operator=(const ValueBase& x)
463         {
464                 if(!x.same_type_as(T()))
465                         throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
466                 return ValueBase::operator=(x);
467         }
468
469 }; // END of class Value
470
471 }; // END of namespace synfig
472
473 /* === E N D =============================================================== */
474
475 #endif