- Main Page
- Related Pages
- Namespaces
- Classes
- Files

# value.h

Go to the documentation of this file.

    00001 /* === S Y N F I G ========================================================= */
    00022 /* ========================================================================= */
    00023
    00024 /* === S T A R T =========================================================== */
    00025
    00026 #ifndef __SYNFIG_VALUE_H
    00027 #define __SYNFIG_VALUE_H
    00028
    00029 /* === H E A D E R S ======================================================= */
    00030
    00031 //#include "vector.h"
    00032 //#include "time.h"
    00033 #include "segment.h"
    00034 //#include "color.h"
    00035 #include "string.h"
    00036 #include <list>
    00037 #include <vector>
    00038 #include <ETL/trivial>
    00039 #include <ETL/handle>
    00040 #include "general.h"
    00041 //#include "gradient.h"
    00042 #include "blinepoint.h"
    00043 #include "exception.h"
    00044
    00045 #ifdef USE_HALF_TYPE
    00046 #include <OpenEXR/half.h>
    00047 #endif
    00048
    00049 #ifndef SYNFIG_NO_ANGLE
    00050 #include "angle.h"
    00051 #endif
    00052
    00053 #include <ETL/ref_count>
    00054
    00055 /* === M A C R O S ========================================================= */
    00056
    00057 /* === T Y P E D E F S ===================================================== */
    00058
    00059 /* === C L A S S E S & S T R U C T S ======================================= */
    00060
    00061 namespace synfig {
    00062
    00063 class Canvas;
    00064 class Vector;
    00065 class Time;
    00066 class Segment;
    00067 class Gradient;
    00068 class BLinePoint;
    00069 class Color;
    00070
    00074 class ValueBase
    00075 {
    00076     /*
    00077  -- ** -- T Y P E S -----------------------------------------------------------
    00078     */
    00079
    00080 public:
    00081
    00083     enum Type
    00084     {
    00085         TYPE_NIL=0,
    00086
    00087         TYPE_BOOL,
    00088         TYPE_INTEGER,
    00089         TYPE_ANGLE,
    00090
    00091         // All types after this point are larger than 32 bits
    00092
    00093         TYPE_TIME,
    00094         TYPE_REAL,
    00095
    00096         // All types after this point are larger than 64 bits
    00097
    00098         TYPE_VECTOR,
    00099         TYPE_COLOR,
    00100         TYPE_SEGMENT,
    00101         TYPE_BLINEPOINT,
    00102
    00103         // All types after this point require construction/destruction
    00104
    00105         TYPE_LIST,
    00106         TYPE_CANVAS,
    00107         TYPE_STRING,
    00108         TYPE_GRADIENT,
    00109
    00110         TYPE_END
    00111     };
    00112
    00113 private:
    00114
    00115     typedef std::vector<ValueBase> list_type;
    00116
    00117     /*
    00118  -- ** -- D A T A -------------------------------------------------------------
    00119     */
    00120
    00121 protected:
    00122
    00123     Type type;
    00124     void *data;
    00125     etl::reference_counter ref_count;
    00126     bool loop_;
    00127
    00128     /*
    00129  -- ** -- C O N S T R U C T O R S -----------------------------------
    00130     */
    00131
    00132 public:
    00133
    00135     ValueBase();
    00136
    00138     template <typename T>
    00139     ValueBase(const T &x, bool loop_=false):
    00140         type(TYPE_NIL),data(0),ref_count(0),loop_(loop_)
    00141         { set(x); }
    00142
    00144     ValueBase(Type x);
    00145
    00147     ~ValueBase();
    00148
    00149     /*
    00150  -- ** -- O P E R A T O R S ---------------------------------------------------
    00151     */
    00152
    00153 public:
    00154
    00156     template <class T> ValueBase& operator=(const T& x)
    00157         { set(x); return *this; }
    00158
    00160     ValueBase& operator=(const ValueBase& x);
    00161
    00163     bool operator==(const ValueBase& rhs)const;
    00164
    00166     bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); }
    00167
    00169     const ValueBase &operator[](int index)const
    00170         { assert(type==TYPE_LIST); assert(index>0); return get_list()[index]; }
    00171
    00172     /*
    00173  -- ** -- M E M B E R   F U N C T I O N S -------------------------------------
    00174     */
    00175
    00176 public:
    00177
    00179     void clear();
    00180
    00182     bool get_loop()const { return loop_; }
    00183
    00185     void set_loop(bool x) { loop_=x; }
    00186
    00188     bool empty()const;
    00189
    00191     Type get_contained_type()const;
    00192
    00194     bool is_valid()const;
    00195
    00197     String type_name()const { return type_name(type); }
    00198
    00200     const Type & get_type()const { return type; }
    00201
    00203     template <class T> bool
    00204     same_type_as(const T &x)const
    00205     {
    00206         const Type testtype(get_type(x));
    00207
    00208         return same_type_as(type, testtype);
    00209     }
    00210
    00211     bool same_type_as(const Type testtype)const
    00212     {
    00213         return same_type_as(type, testtype);
    00214     }
    00215
    00217     static bool same_type_as(const Type type1, const Type type2)
    00218     {
    00219         if (type1 == type2) return true;
    00220         if ((type1 == TYPE_REAL || type1 == TYPE_TIME) &&
    00221             (type2 == TYPE_REAL || type2 == TYPE_TIME))
    00222             return true;
    00223         return false;
    00224     }
    00225
    00226
    00227     // === GET MEMBERS ========================================================
    00228     template <typename T>
    00229     const T &get(const T& x __attribute__ ((unused)))const
    00230     {
    00231         assert(is_valid() && same_type_as(x));
    00232         return *static_cast<const T*>(data);
    00233     }
    00234     float get(const float &)const { return get(Real()); }
    00235     etl::loose_handle<Canvas> get(const etl::handle<Canvas>&)const
    00236         { return get(etl::loose_handle<Canvas>()); }
    00237     etl::loose_handle<Canvas> get(Canvas*)const
    00238         { return get(etl::loose_handle<Canvas>()); }
    00239     const char* get(const char*)const;
    00240     const list_type& get_list()const { return get(list_type()); }
    00241
    00242 #ifdef _DEBUG
    00243     String get_string() const;
    00244 #endif  // _DEBUG
    00245     // ========================================================================
    00246
    00247
    00248
    00249     // === PUT MEMBERS ========================================================
    00250     template <typename T>
    00251     void put(T* x)const
    00252     {
    00253         assert(same_type_as(*x));
    00254         *x=*static_cast<const T*>(data);
    00255     }
    00256     void put(float* x)const { *x=get(Real()); }
    00257     void put(char** x)const;
    00258     // ========================================================================
    00259
    00260
    00261
    00262     // === SET MEMBERS ========================================================
    00263     template <typename T> void set(const T& x) { _set(x); }
    00264     void set(const float &x) { _set(Real(x)); }
    00265     void set(const list_type &x);
    00266     void set(const char* x);
    00267     void set(char* x);
    00268     void set(Canvas*x);
    00269     void set(etl::loose_handle<Canvas> x);
    00270     void set(etl::handle<Canvas> x);
    00271     template <class T> void set(const std::vector<T> &x)
    00272         { _set(list_type(x.begin(),x.end())); }
    00273     template <class T> void set(const std::list<T> &x)
    00274         { _set(list_type(x.begin(),x.end())); }
    00275     // ========================================================================
    00276
    00277
    00278     /*
    00279  -- ** -- S T A T I C   F U N C T I O N S -------------------------------------
    00280     */
    00281
    00282 public:
    00283
    00285     static String type_name(Type id);
    00286
    00288     static String type_local_name(Type id);
    00289
    00291     static Type ident_type(const String &str);
    00292
    00293
    00294     // === GET TYPE MEMBERS ===================================================
    00295     static Type get_type(bool) { return TYPE_BOOL; }
    00296     static Type get_type(int) { return TYPE_INTEGER; }
    00297     static Type get_type(const Time&) { return TYPE_TIME; }
    00298     static Type get_type(const Real&) { return TYPE_REAL; }
    00299     static Type get_type(const float&) { return TYPE_REAL; }
    00300     static Type get_type(const Vector&) { return TYPE_VECTOR; }
    00301     static Type get_type(const Color&) { return TYPE_COLOR; }
    00302     static Type get_type(const Segment&) { return TYPE_SEGMENT; }
    00303     static Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; }
    00304     static Type get_type(const String&) { return TYPE_STRING; }
    00305     static Type get_type(const Gradient&) { return TYPE_GRADIENT; }
    00306     static Type get_type(Canvas*) { return TYPE_CANVAS; }
    00307     static Type get_type(const etl::handle<Canvas>&)
    00308         { return TYPE_CANVAS; }
    00309     static Type get_type(const etl::loose_handle<Canvas>&)
    00310         { return TYPE_CANVAS; }
    00311     static Type get_type(const list_type&) { return TYPE_LIST; }
    00312     template <class T> static Type get_type(const std::vector<T> &/*x*/)
    00313         { return TYPE_LIST; }
    00314     template <class T> static Type get_type(const std::list<T> &/*x*/)
    00315         { return TYPE_LIST; }
    00316     // ========================================================================
    00317
    00318
    00319     /*
    00320  -- ** -- C A S T   O P E R A T O R S -----------------------------------------
    00321     */
    00322
    00323 public:
    00324
    00325     operator const list_type&()const { return get_list(); }
    00326     //operator const Color&()const { return get(Color()); }
    00327     operator const Real&()const { return get(Real()); }
    00328     //operator const Time&()const { return get(Time()); }
    00329
    00330     operator const Vector&()const {  return get(Vector()); }
    00331     operator const BLinePoint&()const {  return get(BLinePoint()); }
    00332     //operator const int&()const {  return get(int()); }
    00333     //operator const String&()const {  return get(String()); }
    00334     //operator const char *()const {  return get(String()).c_str(); }
    00335     operator const Segment&()const { return get(Segment()); }
    00336
    00337
    00338     /*
    00339  -- ** -- O T H E R -----------------------------------------------------------
    00340     */
    00341
    00342 public:
    00343
    00344 #ifdef USE_HALF_TYPE
    00345     half get(const half &)const { return get(Real()); }
    00346     void put(half*x)const { *x=get(Real()); }
    00347     void set(const half &x) { _set(Real(x)); }
    00348     static Type get_type(const half&) { return TYPE_REAL; }
    00349     operator half()const { return get(Real()); }
    00350 #endif
    00351
    00352 #ifndef SYNFIG_NO_ANGLE
    00353     operator const Angle&()const { return get(Angle()); }
    00354     static Type get_type(const Angle&) { return TYPE_ANGLE; }
    00355 #endif
    00356
    00357     template <class T>
    00358     operator std::list<T>()const
    00359     {
    00360         assert(type==TYPE_LIST);
    00361         std::list<T> ret(get_list().begin(),get_list().end());
    00362         return ret;
    00363     }
    00364     template <class T>
    00365     operator std::vector<T>()const
    00366     {
    00367         assert(type==TYPE_LIST);
    00368         std::vector<T> ret(get_list().begin(),get_list().end());
    00369         return ret;
    00370     }
    00371
    00372
    00373 private:
    00374
    00375     template <typename T> void
    00376     _set(const T& x)
    00377     {
    00378         const Type newtype(get_type(x));
    00379
    00380         assert(newtype!=TYPE_NIL);
    00381
    00382         if(newtype==type)
    00383         {
    00384             if(ref_count.unique())
    00385             {
    00386                 *reinterpret_cast<T*>(data)=x;
    00387                 return;
    00388             }
    00389         }
    00390
    00391         clear();
    00392
    00393         type=newtype;
    00394         ref_count.reset();
    00395         data=new T(x);
    00396     }
    00397 }; // END of class ValueBase
    00398
    00399
    00403 template <class T>
    00404 class Value : public ValueBase
    00405 {
    00406 public:
    00407     Value(const T &x):ValueBase(x)
    00408     {
    00409     }
    00410
    00411     Value(const ValueBase &x):ValueBase(x)
    00412     {
    00413         if(!x.same_type_as(T()))
    00414             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
    00415     }
    00416
    00417     Value()
    00418     {
    00419     }
    00420
    00421     T get()const { return ValueBase::get(T()); }
    00422
    00423     void put(T* x)const { ValueBase::put(x); }
    00424
    00425     void set(const T& x) { ValueBase::operator=(x); }
    00426
    00427     Value<T>& operator=(const T& x) { set(x); return *this; }
    00428
    00429     Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
    00430
    00431     Value<T>& operator=(const ValueBase& x)
    00432     {
    00433         if(!x.same_type_as(T()))
    00434             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
    00435         return ValueBase::operator=(x);
    00436     }
    00437
    00438 }; // END of class Value
    00439
    00440 /*
    00441 template <>
    00442 class Value< std::list<CT> > : public ValueBase
    00443 {
    00444 public:
    00445     Value(const T &x):ValueBase(x)
    00446     {
    00447     }
    00448     Value(const ValueBase &x):ValueBase(x)
    00449     {
    00450         if(!x.same_type_as(T()))
    00451             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
    00452     }
    00453     Value()
    00454     {
    00455     }
    00456
    00457     T get()const { return ValueBase::get(T()); }
    00458
    00459     void put(T* x)const { ValueBase::put(x); }
    00460
    00461     void set(const T& x) { ValueBase::operator=(x); }
    00462
    00463     Value<T>& operator=(const T& x) { set(x); return *this; }
    00464
    00465     Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
    00466
    00467     Value<T>& operator=(const ValueBase& x)
    00468     {
    00469         if(!x.same_type_as(T()))
    00470             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
    00471         return ValueBase::operator=(x);
    00472     }
    00473
    00474 }; // END of class Value
    00475 */
    00476
    00477 }; // END of namespace synfig
    00478
    00479 /* === E N D =============================================================== */
    00480
    00481 #endif