Fix bugs in previous commit that caused FTBFS in synfig and ETL FTBFS with older...
[synfig.git] / synfig-core / tags / synfig_0_61_04 / synfig-core / src / synfig / value.cpp
1 /* === S Y N F I G ========================================================= */
2 /*!     \file value.cpp
3 **      \brief Template Header
4 **
5 **      $Id: value.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 **      This package is free software; you can redistribute it and/or
11 **      modify it under the terms of the GNU General Public License as
12 **      published by the Free Software Foundation; either version 2 of
13 **      the License, or (at your option) any later version.
14 **
15 **      This package is distributed in the hope that it will be useful,
16 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
17 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 **      General Public License for more details.
19 **      \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 #       include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 #       include <config.h>
30 #endif
31
32 #include "value.h"
33 #include "general.h"
34 #include <ETL/stringf>
35 #include "canvas.h"
36 #include "gradient.h"
37
38
39
40 #include "vector.h"
41 #include "time.h"
42 #include "segment.h"
43 #include "color.h"
44
45 #endif
46
47 using namespace synfig;
48 using namespace std;
49 using namespace etl;
50
51 /* === M A C R O S ========================================================= */
52
53 /* === G L O B A L S ======================================================= */
54
55 /* === P R O C E D U R E S ================================================= */
56
57 /* === M E T H O D S ======================================================= */
58
59 ValueBase::ValueBase():type(TYPE_NIL),data(0),ref_count(0),loop_(0)
60 {
61 }
62
63 ValueBase::ValueBase(Type x):
64         type(x),
65         data(0),
66         loop_(0)
67 {
68
69         switch(type)
70         {
71         case TYPE_BOOL:
72                 data=static_cast<void*>(new bool());
73                 break;
74         case TYPE_INTEGER:
75                 data=static_cast<void*>(new int());
76                 break;
77         case TYPE_ANGLE:
78                 data=static_cast<void*>(new Angle());
79                 break;
80         case TYPE_VECTOR:
81                 data=static_cast<void*>(new Vector());
82                 break;
83         case TYPE_TIME:
84                 data=static_cast<void*>(new Time());
85                 break;
86         case TYPE_REAL:
87                 data=static_cast<void*>(new Real());
88                 break;
89         case TYPE_COLOR:
90                 data=static_cast<void*>(new Color());
91                 break;
92         case TYPE_SEGMENT:
93                 data=static_cast<void*>(new Segment());
94                 break;
95         case TYPE_BLINEPOINT:
96                 data=static_cast<void*>(new BLinePoint());
97                 break;
98         case TYPE_LIST:
99                 data=static_cast<void*>(new list_type());
100                 break;
101         case TYPE_STRING:
102                 data=static_cast<void*>(new String());
103                 break;
104         case TYPE_GRADIENT:
105                 data=static_cast<void*>(new Gradient());
106                 break;
107         case TYPE_CANVAS:
108                 data=static_cast<void*>(new etl::handle<Canvas>());
109                 break;
110         default:
111                 break;
112         }
113 }
114
115 ValueBase::~ValueBase()
116 {
117         clear();
118 }
119
120 const char*
121 ValueBase::get(const char*)const
122 {
123         return get(String()).c_str();
124 }
125
126
127
128
129 void
130 ValueBase::set(Canvas* x)
131 {
132         clear();
133         if(x && x->is_inline())
134         {
135                 _set(etl::handle<Canvas>(x));
136         }
137         else
138         {
139                 _set(etl::loose_handle<Canvas>(x));
140         }
141         assert(get(x)==x);
142 }
143
144 void
145 ValueBase::set(etl::loose_handle<Canvas> x)
146 {
147         clear();
148         if(x && x->is_inline())
149         {
150                 _set(etl::handle<Canvas>(x));
151         }
152         else
153         {
154                 _set(etl::loose_handle<Canvas>(x));
155         }
156         assert(get(x)==x);
157 }
158
159 void
160 ValueBase::set(etl::handle<Canvas> x)
161 {
162         clear();
163         if(x && x->is_inline())
164         {
165                 _set(etl::handle<Canvas>(x));
166         }
167         else
168         {
169                 _set(etl::loose_handle<Canvas>(x));
170         }
171         assert(get(x)==x);
172 }
173
174 void
175 ValueBase::set(const list_type &x)
176 {
177         _set(x);
178 }
179
180 void
181 ValueBase::set(const char* x)
182 {
183         _set(String(x));
184 }
185
186 bool
187 ValueBase::is_valid()const
188 {
189         return type>TYPE_NIL && type<TYPE_END && ref_count;
190 }
191
192 bool
193 ValueBase::empty()const
194 {
195         return !is_valid() || ((type==TYPE_LIST)?get_list().empty():false);
196 }
197
198 ValueBase::Type
199 ValueBase::get_contained_type()const
200 {
201         if(type!=TYPE_LIST || empty())
202                 return TYPE_NIL;
203         return get_list().front().get_type();
204 }
205
206 ValueBase&
207 ValueBase::operator=(const ValueBase& x)
208 {
209         if(data!=x.data)
210         {
211                 clear();
212                 type=x.type;
213                 data=x.data;
214                 ref_count=x.ref_count;
215         }
216         loop_=x.loop_;
217         return *this;
218 }
219
220 void
221 ValueBase::clear()
222 {
223         if(ref_count.unique() && data)
224         {
225                 switch(type)
226                 {
227                 case TYPE_BOOL:
228                         delete static_cast<bool*>(data);
229                         break;
230                 case TYPE_INTEGER:
231                         delete static_cast<int*>(data);
232                         break;
233                 case TYPE_ANGLE:
234                         delete static_cast<Angle*>(data);
235                         break;
236                 case TYPE_VECTOR:
237                         delete static_cast<Vector*>(data);
238                         break;
239                 case TYPE_TIME:
240                         delete static_cast<Time*>(data);
241                         break;
242                 case TYPE_REAL:
243                         delete static_cast<Real*>(data);
244                         break;
245                 case TYPE_COLOR:
246                         delete static_cast<Color*>(data);
247                         break;
248                 case TYPE_SEGMENT:
249                         delete static_cast<Segment*>(data);
250                         break;
251                 case TYPE_BLINEPOINT:
252                         delete static_cast<BLinePoint*>(data);
253                         break;
254                 case TYPE_LIST:
255                         delete static_cast<list_type*>(data);
256                         break;
257                 case TYPE_STRING:
258                         delete static_cast<String*>(data);
259                         break;
260                 case TYPE_GRADIENT:
261                         delete static_cast<Gradient*>(data);
262                         break;
263
264
265                 case TYPE_CANVAS:
266                 {
267                         etl::handle<Canvas> canvas(get(etl::loose_handle<Canvas>()));
268                         if(canvas && canvas->is_inline())
269                         {
270                                 delete static_cast<etl::handle<Canvas>*>(data);
271                         }
272                         else
273                         {
274                                 delete static_cast<etl::loose_handle<Canvas>*>(data);
275                         }
276                         break;
277                 }
278                 default:
279                         break;
280                 }
281         }
282         
283         ref_count.detach();
284         data=0;
285         type=TYPE_NIL;
286 }
287
288
289 String
290 ValueBase::type_name(Type id)
291 {
292         switch(id)
293         {
294         case TYPE_REAL:
295                 return "real";
296         case TYPE_TIME:
297                 return "time";
298         case TYPE_INTEGER:
299                 return "integer";
300         case TYPE_BOOL:
301                 return "bool";
302         case TYPE_ANGLE:
303                 return "angle";
304         case TYPE_VECTOR:
305                 return "vector";
306         case TYPE_COLOR:
307                 return "color";
308         case TYPE_STRING:
309                 return "string";
310         case TYPE_CANVAS:
311                 return "canvas";
312         case TYPE_LIST:
313                 return "list";
314         case TYPE_SEGMENT:
315                 return "segment";
316         case TYPE_GRADIENT:
317                 return "gradient";
318         case TYPE_BLINEPOINT:
319                 return "bline_point";
320         case TYPE_NIL:
321                 return "nil";
322         default:
323                 break;
324         }
325         synfig::warning("Encountered unknown ValueBase with an Type of %d",id);
326 //      assert(0);
327         return "UNKNOWN";
328 }
329
330 ValueBase::Type
331 ValueBase::ident_type(const String &str)
332 {
333         if(str=="nil" || str=="null")
334                 return TYPE_NIL;
335         else if(str=="time" || str==_("time"))
336                 return TYPE_TIME;
337         else if(str=="real" || str=="float" || str==_("real"))
338                 return TYPE_REAL;
339         else if(str=="integer" || str=="int" || str==_("integer"))
340                 return TYPE_INTEGER;
341         else if(str=="bool" || str==_("bool"))
342                 return TYPE_BOOL;
343         else if(str=="angle" || str=="degrees" || str=="radians" || str=="rotations")
344                 return TYPE_ANGLE;
345         else if(str=="vector" || str=="point")
346                 return TYPE_VECTOR;
347         else if(str=="color")
348                 return TYPE_COLOR;
349         else if(str=="string")
350                 return TYPE_STRING;
351         else if(str=="canvas")
352                 return TYPE_CANVAS;
353         else if(str=="list")
354                 return TYPE_LIST;
355         else if(str=="segment")
356                 return TYPE_SEGMENT;
357         else if(str=="gradient")
358                 return TYPE_GRADIENT;
359         else if(str=="bline_point" || str=="blinepoint")
360                 return TYPE_BLINEPOINT;
361
362         return TYPE_NIL;
363 }
364
365 bool
366 ValueBase::operator==(const ValueBase& rhs)const
367 {
368         if(get_type()!=rhs.get_type())
369                 return false;
370         if(data==rhs.data)
371                 return true;
372         
373         switch(get_type())
374         {
375         case TYPE_TIME:
376                 return get(Time()).is_equal(rhs.get(Time()));
377         case TYPE_REAL:
378                 return abs(get(Real())-rhs.get(Real()))<=0.00000000000001;
379         case TYPE_INTEGER:
380                 return get(int())==rhs.get(int());
381         case TYPE_BOOL:
382                 return get(bool())==rhs.get(bool());
383         case TYPE_ANGLE:
384                 return get(Angle())==rhs.get(Angle());
385         case TYPE_VECTOR:
386                 return get(Vector()).is_equal_to(rhs.get(Vector()));
387         case TYPE_COLOR:
388                 return get(Color())==rhs.get(Color());
389         case TYPE_STRING:
390                 return get(String())==rhs.get(String());
391         case TYPE_CANVAS:
392                 return get(Canvas::LooseHandle())==rhs.get(Canvas::LooseHandle());
393         case TYPE_LIST:
394                 return get_list()==rhs.get_list();
395         case TYPE_SEGMENT:
396 //              return get(Segment())==rhs.get(Segment());
397         case TYPE_GRADIENT:
398 //              return get(Gradient())==rhs.get(Gradient());
399         case TYPE_BLINEPOINT:
400 //              return get(BLinePoint())==rhs.get(BLinePoint());
401         case TYPE_NIL:
402         default:
403                 return false;
404                 break;
405         }
406         return false;
407 }