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(testtype);
00209     }
00210 
00211     bool same_type_as(const Type testtype)const
00212     {
00213         if(testtype==type)return true;
00214         if( (type==TYPE_REAL || type==TYPE_TIME) &&
00215             (testtype==TYPE_REAL || testtype==TYPE_TIME) )
00216             return true;
00217         return false;
00218     }
00219 
00220 
00221     // === GET MEMBERS ========================================================
00222     template <typename T>
00223     const T &get(const T& x)const
00224     {
00225         assert(is_valid() && same_type_as(x));
00226         return *static_cast<const T*>(data);
00227     }
00228     float get(const float &)const { return get(Real()); }
00229     etl::loose_handle<Canvas> get(const etl::handle<Canvas>&)const
00230         { return get(etl::loose_handle<Canvas>()); }
00231     etl::loose_handle<Canvas> get(Canvas*)const
00232         { return get(etl::loose_handle<Canvas>()); }
00233     const char* get(const char*)const;
00234     const list_type& get_list()const { return get(list_type()); }
00235     // ========================================================================
00236 
00237 
00238 
00239     // === PUT MEMBERS ========================================================
00240     template <typename T>
00241     void put(T* x)const
00242     {
00243         assert(same_type_as(*x));
00244         *x=*static_cast<const T*>(data);
00245     }
00246     void put(float* x)const { *x=get(Real()); }
00247     void put(char** x)const;
00248     // ========================================================================
00249 
00250 
00251 
00252     // === SET MEMBERS ========================================================
00253     template <typename T> void set(const T& x) { _set(x); }
00254     void set(const float &x) { _set(Real(x)); }
00255     void set(const list_type &x);
00256     void set(const char* x);
00257     void set(Canvas*x);
00258     void set(etl::loose_handle<Canvas> x);
00259     void set(etl::handle<Canvas> x);
00260     template <class T> void set(const std::vector<T> &x)
00261         { _set(list_type(x.begin(),x.end())); }
00262     template <class T> void set(const std::list<T> &x)
00263         { _set(list_type(x.begin(),x.end())); }
00264     // ========================================================================
00265 
00266 
00267     /*
00268  -- ** -- S T A T I C   F U N C T I O N S -------------------------------------
00269     */
00270 
00271 public:
00272 
00274     static String type_name(Type id);
00275 
00277     static Type ident_type(const String &str);
00278 
00279 
00280     // === GET TYPE MEMBERS ===================================================
00281     static const Type get_type(bool) { return TYPE_BOOL; }
00282     static const Type get_type(int) { return TYPE_INTEGER; }
00283     static const Type get_type(const Time&) { return TYPE_TIME; }
00284     static const Type get_type(const Real&) { return TYPE_REAL; }
00285     static const Type get_type(const float&) { return TYPE_REAL; }
00286     static const Type get_type(const Vector&) { return TYPE_VECTOR; }
00287     static const Type get_type(const Color&) { return TYPE_COLOR; }
00288     static const Type get_type(const Segment&) { return TYPE_SEGMENT; }
00289     static const Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; }
00290     static const Type get_type(const String&) { return TYPE_STRING; }
00291     static const Type get_type(const Gradient&) { return TYPE_GRADIENT; }
00292     static const Type get_type(Canvas*) { return TYPE_CANVAS; }
00293     static const Type get_type(const etl::handle<Canvas>&)
00294         { return TYPE_CANVAS; }
00295     static const Type get_type(const etl::loose_handle<Canvas>&)
00296         { return TYPE_CANVAS; }
00297     static const Type get_type(const list_type&) { return TYPE_LIST; }
00298     template <class T> static const Type get_type(const std::vector<T> &/*x*/)
00299         { return TYPE_LIST; }
00300     template <class T> static const Type get_type(const std::list<T> &/*x*/)
00301         { return TYPE_LIST; }
00302     // ========================================================================
00303 
00304 
00305     /*
00306  -- ** -- C A S T   O P E R A T O R S -----------------------------------------
00307     */
00308 
00309 public:
00310 
00311     operator const list_type&()const { return get_list(); }
00312     //operator const Color&()const { return get(Color()); }
00313     //operator const Real&()const { return get(Real()); }
00314     //operator const Time&()const { return get(Time()); }
00315 
00316     operator const Vector&()const {  return get(Vector()); }
00317     operator const BLinePoint&()const {  return get(BLinePoint()); }
00318     //operator const int&()const {  return get(int()); }
00319     //operator const String&()const {  return get(String()); }
00320     //operator const char *()const {  return get(String()).c_str(); }
00321     operator const Segment&()const { return get(Segment()); }
00322 
00323 
00324     /*
00325  -- ** -- O T H E R -----------------------------------------------------------
00326     */
00327 
00328 public:
00329 
00330 #ifdef USE_HALF_TYPE
00331     half get(const half &)const { return get(Real()); }
00332     void put(half*x)const { *x=get(Real()); }
00333     void set(const half &x) { _set(Real(x)); }
00334     static const Type get_type(const half&) { return TYPE_REAL; }
00335     operator half()const { return get(Real()); }
00336 #endif
00337 
00338 #ifndef SYNFIG_NO_ANGLE
00339     operator const Angle&()const { return get(Angle()); }
00340     static const Type get_type(const Angle&) { return TYPE_ANGLE; }
00341 #endif
00342 
00343     template <class T>
00344     operator std::list<T>()const
00345     {
00346         assert(type==TYPE_LIST);
00347         std::list<T> ret(get_list().begin(),get_list().end());
00348         return ret;
00349     }
00350     template <class T>
00351     operator std::vector<T>()const
00352     {
00353         assert(type==TYPE_LIST);
00354         std::vector<T> ret(get_list().begin(),get_list().end());
00355         return ret;
00356     }
00357 
00358 
00359 private:
00360 
00361     template <typename T> void
00362     _set(const T& x)
00363     {
00364         const Type newtype(get_type(x));
00365 
00366         assert(newtype!=TYPE_NIL);
00367 
00368         if(newtype==type)
00369         {
00370             if(ref_count.unique())
00371             {
00372                 *reinterpret_cast<T*>(data)=x;
00373                 return;
00374             }
00375         }
00376 
00377         clear();
00378 
00379         type=newtype;
00380         ref_count.reset();
00381         data=new T(x);
00382     }
00383 }; // END of class ValueBase
00384 
00385 
00389 template <class T>
00390 class Value : public ValueBase
00391 {
00392 public:
00393     Value(const T &x):ValueBase(x)
00394     {
00395     }
00396 
00397     Value(const ValueBase &x):ValueBase(x)
00398     {
00399         if(!x.same_type_as(T()))
00400             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
00401     }
00402 
00403     Value()
00404     {
00405     }
00406 
00407     T get()const { return ValueBase::get(T()); }
00408 
00409     void put(T* x)const { ValueBase::put(x); }
00410 
00411     void set(const T& x) { ValueBase::operator=(x); }
00412 
00413     Value<T>& operator=(const T& x) { set(x); return *this; }
00414 
00415     Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
00416 
00417     Value<T>& operator=(const ValueBase& x)
00418     {
00419         if(!x.same_type_as(T()))
00420             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
00421         return ValueBase::operator=(x);
00422     }
00423 
00424 }; // END of class Value
00425 
00426 /*
00427 template <>
00428 class Value< std::list<CT> > : public ValueBase
00429 {
00430 public:
00431     Value(const T &x):ValueBase(x)
00432     {
00433     }
00434     Value(const ValueBase &x):ValueBase(x)
00435     {
00436         if(!x.same_type_as(T()))
00437             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
00438     }
00439     Value()
00440     {
00441     }
00442 
00443     T get()const { return ValueBase::get(T()); }
00444 
00445     void put(T* x)const { ValueBase::put(x); }
00446 
00447     void set(const T& x) { ValueBase::operator=(x); }
00448 
00449     Value<T>& operator=(const T& x) { set(x); return *this; }
00450 
00451     Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
00452 
00453     Value<T>& operator=(const ValueBase& x)
00454     {
00455         if(!x.same_type_as(T()))
00456             throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
00457         return ValueBase::operator=(x);
00458     }
00459 
00460 }; // END of class Value
00461 */
00462 
00463 }; // END of namespace synfig
00464 
00465 /* === E N D =============================================================== */
00466 
00467 #endif

Generated on Wed Dec 12 03:11:41 2007 for synfig by  doxygen 1.5.4