00001
00021
00022
00023
00024
00025 #ifndef __SYNFIG_VALUE_H
00026 #define __SYNFIG_VALUE_H
00027
00028
00029
00030
00031
00032 #include "segment.h"
00033
00034 #include "string.h"
00035 #include <list>
00036 #include <vector>
00037 #include <ETL/trivial>
00038 #include <ETL/handle>
00039 #include "general.h"
00040
00041 #include "blinepoint.h"
00042 #include "exception.h"
00043
00044 #ifdef USE_HALF_TYPE
00045 #include <OpenEXR/half.h>
00046 #endif
00047
00048 #ifndef SYNFIG_NO_ANGLE
00049 #include "angle.h"
00050 #endif
00051
00052 #include <ETL/ref_count>
00053
00054
00055
00056
00057
00058
00059
00060 namespace synfig {
00061
00062 class Canvas;
00063 class Vector;
00064 class Time;
00065 class Segment;
00066 class Gradient;
00067 class BLinePoint;
00068 class Color;
00069
00073 class ValueBase
00074 {
00075
00076
00077
00078
00079 public:
00080
00082 enum Type
00083 {
00084 TYPE_NIL=0,
00085
00086 TYPE_BOOL,
00087 TYPE_INTEGER,
00088 TYPE_ANGLE,
00089
00090
00091
00092 TYPE_TIME,
00093 TYPE_REAL,
00094
00095
00096
00097 TYPE_VECTOR,
00098 TYPE_COLOR,
00099 TYPE_SEGMENT,
00100 TYPE_BLINEPOINT,
00101
00102
00103
00104 TYPE_LIST,
00105 TYPE_CANVAS,
00106 TYPE_STRING,
00107 TYPE_GRADIENT,
00108
00109 TYPE_END
00110 };
00111
00112 private:
00113
00114 typedef std::vector<ValueBase> list_type;
00115
00116
00117
00118
00119
00120 protected:
00121
00122 Type type;
00123 void *data;
00124 etl::reference_counter ref_count;
00125 bool loop_;
00126
00127
00128
00129
00130
00131 public:
00132
00134 ValueBase();
00135
00137 template <typename T>
00138 ValueBase(const T &x, bool loop_=false):
00139 type(TYPE_NIL),data(0),ref_count(0),loop_(loop_)
00140 { set(x); }
00141
00143 ValueBase(Type x);
00144
00146 ~ValueBase();
00147
00148
00149
00150
00151
00152 public:
00153
00155 template <class T> ValueBase& operator=(const T& x)
00156 { set(x); return *this; }
00157
00159 ValueBase& operator=(const ValueBase& x);
00160
00162 bool operator==(const ValueBase& rhs)const;
00163
00165 bool operator!=(const ValueBase& rhs)const { return !operator==(rhs); }
00166
00168 const ValueBase &operator[](int index)const
00169 { assert(type==TYPE_LIST); assert(index>0); return get_list()[index]; }
00170
00171
00172
00173
00174
00175 public:
00176
00178 void clear();
00179
00181 bool get_loop()const { return loop_; }
00182
00184 void set_loop(bool x) { loop_=x; }
00185
00187 bool empty()const;
00188
00190 Type get_contained_type()const;
00191
00193 bool is_valid()const;
00194
00196 String type_name()const { return type_name(type); }
00197
00199 const Type & get_type()const { return type; }
00200
00202 template <class T> bool
00203 same_as(const T &x)const
00204 {
00205 const Type testtype(get_type(x));
00206
00207 if(testtype==type)return true;
00208 if( (type==TYPE_REAL || type==TYPE_TIME) &&
00209 (testtype==TYPE_REAL || testtype==TYPE_TIME) )
00210 return true;
00211 return false;
00212 }
00213
00214
00215
00216 template <typename T>
00217 const T &get(const T& x)const
00218 {
00219 assert(is_valid() && same_as(x));
00220 return *static_cast<const T*>(data);
00221 }
00222 float get(const float &)const { return get(Real()); }
00223 etl::loose_handle<Canvas> get(const etl::handle<Canvas>&)const
00224 { return get(etl::loose_handle<Canvas>()); }
00225 etl::loose_handle<Canvas> get(Canvas*)const
00226 { return get(etl::loose_handle<Canvas>()); }
00227 const char* get(const char*)const;
00228 const list_type& get_list()const { return get(list_type()); }
00229
00230
00231
00232
00233
00234 template <typename T>
00235 void put(T* x)const
00236 {
00237 assert(same_as(*x));
00238 *x=*static_cast<const T*>(data);
00239 }
00240 void put(float* x)const { *x=get(Real()); }
00241 void put(char** x)const;
00242
00243
00244
00245
00246
00247 template <typename T> void set(const T& x) { _set(x); }
00248 void set(const float &x) { _set(Real(x)); }
00249 void set(const list_type &x);
00250 void set(const char* x);
00251 void set(Canvas*x);
00252 void set(etl::loose_handle<Canvas> x);
00253 void set(etl::handle<Canvas> x);
00254 template <class T> void set(const std::vector<T> &x)
00255 { _set(list_type(x.begin(),x.end())); }
00256 template <class T> void set(const std::list<T> &x)
00257 { _set(list_type(x.begin(),x.end())); }
00258
00259
00260
00261
00262
00263
00264
00265 public:
00266
00268 static String type_name(Type id);
00269
00271 static Type ident_type(const String &str);
00272
00273
00274
00275 static const Type get_type(bool) { return TYPE_BOOL; }
00276 static const Type get_type(int) { return TYPE_INTEGER; }
00277 static const Type get_type(const Time&) { return TYPE_TIME; }
00278 static const Type get_type(const Real&) { return TYPE_REAL; }
00279 static const Type get_type(const float&) { return TYPE_REAL; }
00280 static const Type get_type(const Vector&) { return TYPE_VECTOR; }
00281 static const Type get_type(const Color&) { return TYPE_COLOR; }
00282 static const Type get_type(const Segment&) { return TYPE_SEGMENT; }
00283 static const Type get_type(const BLinePoint&) { return TYPE_BLINEPOINT; }
00284 static const Type get_type(const String&) { return TYPE_STRING; }
00285 static const Type get_type(const Gradient&) { return TYPE_GRADIENT; }
00286 static const Type get_type(Canvas*) { return TYPE_CANVAS; }
00287 static const Type get_type(const etl::handle<Canvas>&)
00288 { return TYPE_CANVAS; }
00289 static const Type get_type(const etl::loose_handle<Canvas>&)
00290 { return TYPE_CANVAS; }
00291 static const Type get_type(const list_type&) { return TYPE_LIST; }
00292 template <class T> static const Type get_type(const std::vector<T> &x)
00293 { return TYPE_LIST; }
00294 template <class T> static const Type get_type(const std::list<T> &x)
00295 { return TYPE_LIST; }
00296
00297
00298
00299
00300
00301
00302
00303 public:
00304
00305 operator const list_type&()const { return get_list(); }
00306
00307
00308
00309
00310 operator const Vector&()const { return get(Vector()); }
00311 operator const BLinePoint&()const { return get(BLinePoint()); }
00312
00313
00314
00315 operator const Segment&()const { return get(Segment()); }
00316
00317
00318
00319
00320
00321
00322 public:
00323
00324 #ifdef USE_HALF_TYPE
00325 half get(const half &)const { return get(Real()); }
00326 void put(half*x)const { *x=get(Real()); }
00327 void set(const half &x) { _set(Real(x)); }
00328 static const Type get_type(const half&) { return TYPE_REAL; }
00329 operator half()const { return get(Real()); }
00330 #endif
00331
00332 #ifndef SYNFIG_NO_ANGLE
00333 operator const Angle&()const { return get(Angle()); }
00334 static const Type get_type(const Angle&) { return TYPE_ANGLE; }
00335 #endif
00336
00337 template <class T>
00338 operator std::list<T>()const
00339 {
00340 assert(type==TYPE_LIST);
00341 std::list<T> ret(get_list().begin(),get_list().end());
00342 return ret;
00343 }
00344 template <class T>
00345 operator std::vector<T>()const
00346 {
00347 assert(type==TYPE_LIST);
00348 std::vector<T> ret(get_list().begin(),get_list().end());
00349 return ret;
00350 }
00351
00352
00353 private:
00354
00355 template <typename T> void
00356 _set(const T& x)
00357 {
00358 const Type newtype(get_type(x));
00359
00360 assert(newtype!=TYPE_NIL);
00361
00362 if(newtype==type)
00363 {
00364 if(ref_count.unique())
00365 {
00366 *reinterpret_cast<T*>(data)=x;
00367 return;
00368 }
00369 }
00370
00371 clear();
00372
00373 type=newtype;
00374 ref_count.reset();
00375 data=new T(x);
00376 }
00377 };
00378
00379
00383 template <class T>
00384 class Value : public ValueBase
00385 {
00386 public:
00387 Value(const T &x):ValueBase(x)
00388 {
00389 }
00390
00391 Value(const ValueBase &x):ValueBase(x)
00392 {
00393 if(!x.same_as(T()))
00394 throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
00395 }
00396
00397 Value()
00398 {
00399 }
00400
00401 T get()const { return ValueBase::get(T()); }
00402
00403 void put(T* x)const { ValueBase::put(x); }
00404
00405 void set(const T& x) { ValueBase::operator=(x); }
00406
00407 Value<T>& operator=(const T& x) { set(x); return *this; }
00408
00409 Value<T>& operator=(const Value<T>& x) { return ValueBase::operator=(x); }
00410
00411 Value<T>& operator=(const ValueBase& x)
00412 {
00413 if(!x.same_as(T()))
00414 throw Exception::BadType("Value<T>(ValueBase): Type Mismatch");
00415 return ValueBase::operator=(x);
00416 }
00417
00418 };
00419
00420
00421
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 #endif