00001
00022
00023
00024
00025
00026 #ifndef __SYNFIG_VALUE_H
00027 #define __SYNFIG_VALUE_H
00028
00029
00030
00031
00032
00033 #include "segment.h"
00034
00035 #include "string.h"
00036 #include <list>
00037 #include <vector>
00038 #include <ETL/trivial>
00039 #include <ETL/handle>
00040 #include "general.h"
00041
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
00056
00057
00058
00059
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
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
00092
00093 TYPE_TIME,
00094 TYPE_REAL,
00095
00096
00097
00098 TYPE_VECTOR,
00099 TYPE_COLOR,
00100 TYPE_SEGMENT,
00101 TYPE_BLINEPOINT,
00102
00103
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
00119
00120
00121 protected:
00122
00123 Type type;
00124 void *data;
00125 etl::reference_counter ref_count;
00126 bool loop_;
00127
00128
00129
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
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
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
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
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
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
00269
00270
00271 public:
00272
00274 static String type_name(Type id);
00275
00277 static Type ident_type(const String &str);
00278
00279
00280
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> &)
00299 { return TYPE_LIST; }
00300 template <class T> static const Type get_type(const std::list<T> &)
00301 { return TYPE_LIST; }
00302
00303
00304
00305
00306
00307
00308
00309 public:
00310
00311 operator const list_type&()const { return get_list(); }
00312
00313
00314
00315
00316 operator const Vector&()const { return get(Vector()); }
00317 operator const BLinePoint&()const { return get(BLinePoint()); }
00318
00319
00320
00321 operator const Segment&()const { return get(Segment()); }
00322
00323
00324
00325
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 };
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 };
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463 };
00464
00465
00466
00467 #endif