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