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(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
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
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
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
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
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> &)
00313 { return TYPE_LIST; }
00314 template <class T> static Type get_type(const std::list<T> &)
00315 { return TYPE_LIST; }
00316
00317
00318
00319
00320
00321
00322
00323 public:
00324
00325 operator const list_type&()const { return get_list(); }
00326
00327 operator const Real&()const { return get(Real()); }
00328
00329
00330 operator const Vector&()const { return get(Vector()); }
00331 operator const BLinePoint&()const { return get(BLinePoint()); }
00332
00333
00334
00335 operator const Segment&()const { return get(Segment()); }
00336
00337
00338
00339
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 };
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 };
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
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 };
00478
00479
00480
00481 #endif