synfig-studio  1.0.3
value_desc.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
23 /* ========================================================================= */
24 
25 /* === S T A R T =========================================================== */
26 
27 #ifndef __SYNFIG_APP_VALUE_DESC_H
28 #define __SYNFIG_APP_VALUE_DESC_H
29 
30 /* === H E A D E R S ======================================================= */
31 
32 #include <synfig/valuenode.h>
33 #include <synfig/string.h>
34 #include <synfig/layer.h>
35 #include <synfig/value.h>
36 #include <synfig/valuenodes/valuenode_animated.h>
37 #include <synfig/valuenodes/valuenode_const.h>
38 #include <synfig/canvas.h>
39 #include <synfig/interpolation.h>
40 
41 /* === M A C R O S ========================================================= */
42 
43 /* === T Y P E D E F S ===================================================== */
44 
45 /* === C L A S S E S & S T R U C T S ======================================= */
46 
47 namespace synfigapp {
48 
49 class ValueDesc
50 {
51  // Info for Layer parent
53  synfig::String name;
54 
55  // Info for ValueNode parent
56  synfig::ValueNode::Handle parent_value_node;
57  int index; // -2 if it's a waypoint, -1 if it's const, >=0 if it's LinkableValueNode
58  synfig::Time waypoint_time;
59 
60  // Info for exported ValueNode
62 
63  // Info for visual editon
64  synfig::Real scalar;
65 
66  // Info for sub-value of parent ValueDesc
67  std::vector<synfig::String> sub_names;
68 
69  ValueDesc *parent_desc;
70  int links_count;
71  static const ValueDesc blank;
72 
73  static ValueDesc* init_parent(const ValueDesc& parent)
74  {
75  if (!parent.is_valid()) return NULL;
76  ValueDesc *p = new ValueDesc(parent);
77  p->links_count++;
78  return p;
79  }
80 
81 public:
82  bool operator==(const ValueDesc &rhs)const
83  {
84  if((layer||rhs.layer) && layer!=rhs.layer)
85  return false;
86  if((!name.empty()||!rhs.name.empty()) && name!=rhs.name)
87  return false;
88  if(layer)
89  return true;
90  if((canvas||rhs.canvas) && canvas!=rhs.canvas)
91  return false;
92  if((parent_value_node||rhs.parent_value_node) && (parent_value_node!=rhs.parent_value_node))
93  return false;
94  if(scalar!=rhs.scalar)
95  return false;
96  if(index!=rhs.index)
97  return false;
98  if(sub_names!=rhs.sub_names)
99  return false;
100  return true;
101  }
102 
103  bool operator!=(const ValueDesc &rhs)const
104  {
105  return !operator==(rhs);
106  }
107 
109  {
110  layer = other.layer;
111  name = other.name;
112  parent_value_node = other.parent_value_node;
113  index = other.index;
114  waypoint_time = other.waypoint_time;
115  canvas = other.canvas;
116  scalar = other.scalar;
117  sub_names = other.sub_names;
118  if (parent_desc != NULL && 0 >= --parent_desc->links_count)
119  delete parent_desc;
120  parent_desc = other.parent_desc;
121  if (parent_desc != NULL) parent_desc->links_count++;
122  return *this;
123  }
124 
125  ValueDesc(synfig::Layer::Handle layer,const synfig::String& param_name,const ValueDesc &parent = blank):
126  layer(layer),
127  name(param_name),
128  index(-1),
129  scalar(0),
130  parent_desc(init_parent(parent)),
131  links_count(0)
132  { }
133 
134  ValueDesc(synfig::Layer::LooseHandle layer,const synfig::String& param_name,const ValueDesc &parent = blank):
135  layer(layer),
136  name(param_name),
137  index(-1),
138  scalar(0),
139  parent_desc(init_parent(parent)),
140  links_count(0)
141  { }
142 
143  ValueDesc(synfig::LinkableValueNode::Handle parent_value_node,int index,const ValueDesc &parent = blank):
144  parent_value_node(parent_value_node),
145  index(index),
146  scalar(1.0),
147  parent_desc(init_parent(parent)),
148  links_count(0)
149  { }
150 
151  ValueDesc(synfig::LinkableValueNode::Handle parent_value_node,int index, synfig::Real s,const ValueDesc &parent = blank):
152  parent_value_node(parent_value_node),
153  index(index),
154  scalar(s),
155  parent_desc(init_parent(parent)),
156  links_count(0)
157  { }
158 
159 // ValueDesc(synfig::LinkableValueNode::Handle parent_value_node,const synfig::String& param_name,const ValueDesc &parent = blank):
160 // parent_value_node(parent_value_node),
161 // index(parent_value_node->get_link_index_from_name(param_name)),
162 // parent_desc(init_parent(parent)),
163 // links_count(0)
164 // { }
165 
166  ValueDesc(synfig::ValueNode_Animated::Handle parent_value_node,synfig::Time waypoint_time,const ValueDesc &parent = blank):
167  parent_value_node(parent_value_node),
168  index(-2),
169  waypoint_time(waypoint_time),
170  scalar(0),
171  parent_desc(init_parent(parent)),
172  links_count(0)
173  { }
174 
175  ValueDesc(synfig::Canvas::Handle canvas,const synfig::String& name,const ValueDesc &parent = blank):
176  name(name),
177  index(-1),
178  canvas(canvas),
179  scalar(0),
180  parent_desc(init_parent(parent)),
181  links_count(0)
182  { }
183 
184  ValueDesc(synfig::ValueNode_Const::Handle parent_value_node,const ValueDesc &parent = blank):
185  parent_value_node(parent_value_node),
186  index(-1),
187  scalar(0),
188  parent_desc(init_parent(parent)),
189  links_count(0)
190  { }
191 
192  ValueDesc(const ValueDesc &parent, const synfig::String &sub_name):
193  layer(parent.layer),
194  name(parent.name),
195  parent_value_node(parent.parent_value_node),
196  index(parent.index),
197  waypoint_time(parent.waypoint_time),
198  canvas(parent.canvas),
199  scalar(parent.scalar),
200  parent_desc(init_parent(parent)),
201  links_count(0)
202  {
203  assert(!sub_name.empty());
204  sub_names.reserve(parent.sub_names.size() + 1);
205  sub_names.insert(sub_names.end(), parent.sub_names.begin(), parent.sub_names.end());
206  sub_names.push_back(sub_name);
207  }
208 
209  // copy
210  ValueDesc(const ValueDesc &other):
211  layer(other.layer),
212  name(other.name),
213  parent_value_node(other.parent_value_node),
214  index(other.index),
215  waypoint_time(other.waypoint_time),
216  canvas(other.canvas),
217  scalar(other.scalar),
218  sub_names(other.sub_names),
219  parent_desc(other.parent_desc),
220  links_count(0)
221  {
222  if (parent_desc != NULL) parent_desc->links_count++;
223  }
224 
226  index(-1), scalar(0), parent_desc(NULL), links_count(0) { }
227 
229  {
230  assert(links_count == 0);
231  if (parent_desc != NULL && 0 >= --parent_desc->links_count)
232  delete parent_desc;
233  }
234 
235  // Instrocpection members
236  bool
237  is_valid()const
238  { return layer || parent_value_node || canvas; }
239 
240  operator bool()const { return is_valid(); }
241 
242  bool
244  { return (bool)layer; }
245  bool
247  { return (bool)parent_value_node; }
248  bool
250  { return parent_is_value_node() && index>=0; }
251  bool
253  { return parent_is_value_node() && index==-1; }
254  bool
256  { return parent_is_value_node() && index==-2; }
257  bool
259  { return (bool)canvas; }
260  bool
262  { return !sub_names.empty(); }
263 
264  bool
266  { return parent_is_value_node()
267  || parent_is_canvas()
268  || (parent_is_layer() && (bool)layer->dynamic_param_list().count(name));
269  }
270  bool
271  is_const()const
272  { return (parent_is_layer() && !layer->dynamic_param_list().count(name))
274  || (parent_is_linkable_value_node() && synfig::ValueNode_Const::Handle::cast_dynamic(get_value_node()));
275  }
276 
277  bool
278  is_animated()const
279  { return ( parent_is_layer()
280  && layer->dynamic_param_list().count(name)
281  && synfig::ValueNode_Animated::Handle::cast_dynamic(layer->dynamic_param_list().find(name)->second))
282  || ( parent_is_canvas()
283  && synfig::ValueNode_Animated::Handle::cast_dynamic(get_value_node()));
284  }
285 
286  bool
288  { return parent_desc != NULL; }
289 
290  // Get members
292  { return parent_desc == NULL ? blank : *parent_desc; }
294  { return parent_is_value_desc() ? get_sub_parent_desc().get_origin_desc() : *this ; }
297 
299  get_layer()const
300  { assert(parent_is_layer()); return layer; }
301 
302  const synfig::String&
304  { assert(parent_is_layer()); return name; }
305 
306  bool
307  find_param_desc(synfig::ParamDesc &out_param_desc)const {
308  assert(parent_is_layer());
309  if (layer) {
310  synfig::Layer::Vocab vocab = layer->get_param_vocab();
311  for(synfig::Layer::Vocab::iterator i = vocab.begin(); i != vocab.end(); i++)
312  if (i->get_name() == name)
313  { out_param_desc = *i; return true; }
314  }
315  return false;
316  }
317 
320  { assert(parent_is_value_node()); return parent_value_node; }
321 
322  int
323  get_index()const
324  { assert(parent_is_linkable_value_node()); return index; }
325 
326  synfig::Real
327  get_scalar()const
328  { assert(parent_is_linkable_value_node()); return scalar; }
329 
330  synfig::String
331  get_name()const
332  { assert(parent_is_linkable_value_node()); return (synfig::LinkableValueNode::Handle::cast_reinterpret(parent_value_node))->link_name(index); }
333 
334  const std::vector<synfig::String>&
336  { assert(parent_is_value_desc()); return sub_names; }
337 
338  const synfig::String&
340  { assert(parent_is_value_desc()); return sub_names.front(); }
341 
342  synfig::Time
344  { assert(parent_is_waypoint()); return waypoint_time; }
345 
346  const synfig::String&
348  { assert(parent_is_canvas()); return name; }
349 
351  get_canvas()const
352  {
353  if(canvas)
354  return canvas;
355  if(layer)
356  return layer->get_canvas();
357  if(parent_value_node)
358  return parent_value_node->get_root_canvas();
359  return 0;
360  }
361 
364  {
365  if(parent_is_canvas())
366  return canvas->find_value_node(name,false);
367  if(parent_is_layer() && layer->dynamic_param_list().count(name))
368  return layer->dynamic_param_list().find(name)->second;
370  return (synfig::LinkableValueNode::Handle::cast_reinterpret(parent_value_node))->get_link(index);
371 // return reinterpret_cast<synfig::LinkableValueNode*>(parent_value_node.get())->get_link(index);
373  return parent_value_node;
374  if(parent_is_waypoint())
375  return (synfig::ValueNode_Animated::Handle::cast_reinterpret(parent_value_node))->find(waypoint_time)->get_value_node();
376  return 0;
377  }
378 
379  synfig::ValueBase
380  get_value(synfig::Time time=0)const
381  {
382  // if the value is constant, return that constant value (at *any* time, it doesn't matter which)
384  return (*parent_value_node)(0);
385  if(is_value_node() && get_value_node())
386  return (*get_value_node())(time);
387  if(parent_is_layer() && layer)
388  return layer->get_param(name);
389  return synfig::ValueBase();
390  }
391 
392  synfig::Type&
394  {
396  if(value_node)
397  return value_node->get_type();
398  return get_value().get_type();
399  }
400 
401  bool
402  is_exported()const
403  {
404  return is_value_node() && get_value_node()->is_exported();
405  }
406 
407  synfig::String
408  get_description(bool show_exported_name = true)const;
409 
410  synfig::Interpolation
412  {
413  if(parent_is_layer() && is_const())
414  return get_value().get_interpolation();
415  else
416  {
418  if (value)
419  return value->get_interpolation();
420  else
421  return synfig::Interpolation(5);
422  }
423  }
424 
425  bool
426  get_static()const
427  {
428  if(is_const())
429  return get_value().get_static();
430  return false;
431  }
432 
433  synfig::GUID get_guid()const
434  {
435  if (parent_is_value_desc())
436  return get_sub_parent_desc().get_guid() % synfig::GUID::hasher(get_sub_names().back());
437  if (is_value_node())
438  return get_value_node()->get_guid();
439  if (parent_is_layer())
440  return get_layer()->get_guid() % synfig::GUID::hasher(get_param_name());
441  assert(!is_valid());
442  return synfig::GUID::zero();
443  }
444 
445  synfig::String get_guid_string()const
446  {
447  return get_guid().get_string();
448  }
449 
451  ValueDesc create_sub_value(const synfig::String &sub_name)const
452  {
453  return ValueDesc(*this, sub_name);
454  }
455 
457  ValueDesc get_sub_value(const synfig::String &sub_name)const
458  {
459  return sub_name.empty() ? *this : ValueDesc(*this, sub_name);
460  }
461 }; // END of class ValueDesc
462 
463 }; // END of namespace synfigapp_instance
464 
465 /* === E N D =============================================================== */
466 
467 #endif