Make link_name(), link_local_name, and get_link_index_from_name non pure virtual...
[synfig.git] / synfig-core / src / synfig / valuenode.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode.h
3 **      \brief Header file for implementation of the "Placeholder" valuenode conversion.
4 **
5 **      $Id$
6 **
7 **      \legal
8 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **      Copyright (c) 2008 Chris Moore
10 **
11 **      This package is free software; you can redistribute it and/or
12 **      modify it under the terms of the GNU General Public License as
13 **      published by the Free Software Foundation; either version 2 of
14 **      the License, or (at your option) any later version.
15 **
16 **      This package is distributed in the hope that it will be useful,
17 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
18 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 **      General Public License for more details.
20 **      \endlegal
21 */
22 /* ========================================================================= */
23
24 /* === S T A R T =========================================================== */
25
26 #ifndef __SYNFIG_VALUENODE_H
27 #define __SYNFIG_VALUENODE_H
28
29 /* === H E A D E R S ======================================================= */
30
31 #include "vector.h"
32 #include "value.h"
33 #include "string.h"
34 #include "releases.h"
35 #include <ETL/handle>
36 #include <ETL/stringf>
37 #include "exception.h"
38 #include <map>
39 #include <sigc++/signal.h>
40 #include "guid.h"
41 #include <ETL/angle>
42 #include "paramdesc.h"
43
44 #include "node.h"
45
46 #include <set>
47
48 /* === M A C R O S ========================================================= */
49
50 #define CHECK_TYPE_AND_SET_VALUE(variable, type)                                                \
51         /* I don't think this ever happens - maybe remove this code? */         \
52         if (get_type() == ValueBase::TYPE_NIL) {                                                        \
53                 warning("%s:%d get_type() IS nil sometimes!",                                   \
54                                 __FILE__, __LINE__);                                                                    \
55                 return false;                                                                                                   \
56         }                                                                                                                                       \
57         if (get_type() != ValueBase::TYPE_NIL &&                                                        \
58                 !(ValueBase::same_type_as(value->get_type(), type)) &&                  \
59                 !PlaceholderValueNode::Handle::cast_dynamic(value)) {                   \
60                 error(_("%s:%d wrong type for %s: need %s but got %s"),                 \
61                           __FILE__, __LINE__,                                                                           \
62                           link_local_name(i).c_str(),                                                           \
63                           ValueBase::type_local_name(type).c_str(),                                     \
64                           ValueBase::type_local_name(value->get_type()).c_str());       \
65                 return false;                                                                                                   \
66         }                                                                                                                                       \
67         variable = value;                                                                                                       \
68         signal_child_changed()(i);                                                                                      \
69         signal_value_changed()();                                                                                       \
70         return true
71
72 /* === T Y P E D E F S ===================================================== */
73
74 /* === C L A S S E S & S T R U C T S ======================================= */
75
76 namespace synfig {
77
78 class Canvas;
79 class LinkableValueNode;
80 class Layer;
81 class ParamVocab;
82
83 /*!     \class ValueNode
84 **      \brief Base class for all Value Nodes
85 */
86 class ValueNode : public synfig::Node
87 {
88         friend class Layer;
89         friend class LinkableValueNode;
90
91         /*
92  --     ** -- T Y P E S -----------------------------------------------------------
93         */
94
95 public:
96
97         typedef etl::handle<ValueNode> Handle;
98
99         typedef etl::loose_handle<ValueNode> LooseHandle;
100
101         typedef etl::handle<const ValueNode> ConstHandle;
102
103         typedef etl::rhandle<ValueNode> RHandle;
104
105         //!Instantiates the book of ValaueNodes and register all the valid valuenodes on it
106         static bool subsys_init();
107         //!Deletes the book of ValueNodes
108         static bool subsys_stop();
109
110         /*
111  --     ** -- D A T A -------------------------------------------------------------
112         */
113
114 private:
115         //! The type of the Value Node
116         //! \see ValueBase
117         ValueBase::Type type;
118         //! The name of the Value Node. This is the string that is used in the
119         //! sif file to define the value type: i.e. <param name="amount">
120         String name;
121         //! The canvas this Value Node belongs to
122         etl::loose_handle<Canvas> canvas_;
123         //! The root canvas this Value Node belongs to
124         etl::loose_handle<Canvas> root_canvas_;
125
126         /*
127  -- ** -- S I G N A L S -------------------------------------------------------
128         */
129
130 private:
131
132         //!     ValueBase Changed
133         sigc::signal<void> signal_value_changed_;
134
135         //!     Children Reordered
136         sigc::signal<void,int*> signal_children_reordered_;
137
138         //!     Child Changed
139         sigc::signal<void,int> signal_child_changed_;
140
141         //!     Child Removed
142         sigc::signal<void,int> signal_child_removed_;
143
144         //!     Child Inserted
145         sigc::signal<void,int> signal_child_inserted_;
146
147         //!     ID Changed
148         sigc::signal<void> signal_id_changed_;
149
150         /*
151  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
152         */
153
154 public:
155
156         //!     ValueBase Changed
157         sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
158
159         //!     Children Reordered
160         sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
161
162         //!     Child Changed
163         sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
164
165         //!     Child Removed
166         sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
167
168         //!     Child Inserted
169         sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
170
171         //!     ID Changed
172         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
173
174         /*
175  --     ** -- C O N S T R U C T O R S ---------------------------------------------
176         */
177
178 protected:
179
180         ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
181
182 public:
183
184         virtual ~ValueNode();
185
186         /*
187  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
188         */
189
190 public:
191
192         //! Returns the value of the ValueNode at time \a t
193         virtual ValueBase operator()(Time /*t*/)const
194                 { return ValueBase(); }
195
196         //! \internal Sets the id of the ValueNode
197         void set_id(const String &x);
198
199         //! Returns the id of the ValueNode
200         /*!     The ID is used for keeping track of a
201         **      specific instance of a ValueNode. */
202         const String &get_id()const { return name; }
203
204         //! Returns the name of the ValueNode type
205         virtual String get_name()const=0;
206
207         //! Returns the localized name of the ValueNode type
208         virtual String get_local_name()const=0;
209
210         //! Return a full description of the ValueNode and its parentage
211         virtual String get_description(bool show_exported_name = true)const;
212
213
214         //! Clones a Value Node
215         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
216
217         //! Returns \true if the Value Node has an ID (has been exported)
218         bool is_exported()const { return !get_id().empty(); }
219
220         //! Returns the type of the ValueNode
221         ValueBase::Type get_type()const { return type; }
222
223         //! Returns a handle to the parent canvas, if it has one.
224         etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
225
226         //! Returns a handle to the parent canvas, if it has one.
227         etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
228
229         //! Sets the parent canvas for the Value Node
230         void set_parent_canvas(etl::loose_handle<Canvas> x);
231
232         //! Sets the root canvas parent for the Value Node
233         void set_root_canvas(etl::loose_handle<Canvas> x);
234
235         //! Returns the relative ID of a Node when accessed form the \x Canvas
236         String get_relative_id(etl::loose_handle<const Canvas> x)const;
237
238         //! Replaces the Value Node with a given one. It look up all its parents
239         //! remove it self from them and adds the given Value Node
240         //! Notice that it is called twice and the second time it uses
241         //! a replaceable handle to the Node
242         //! \see etl::rhandle
243         int replace(etl::handle<ValueNode> x);
244
245 protected:
246         //! Sets the type of the ValueNode
247         void set_type(ValueBase::Type t) { type=t; }
248
249         virtual void on_changed();
250 }; // END of class ValueNode
251
252 /*!     \class PlaceholderValueNode
253 **      Seems to be a Place to hold a Value Node temporarly.
254 *
255 *       Doesn't seem to implement any functionality. Seems to be used when the
256 *       value node cannot be created using the Const, Animated or Linkable
257 *       Value Nodes.
258 *
259 */
260 class PlaceholderValueNode : public ValueNode
261 {
262 public:
263         typedef etl::handle<PlaceholderValueNode> Handle;
264         typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
265         typedef etl::handle<const PlaceholderValueNode> ConstHandle;
266         typedef etl::rhandle<PlaceholderValueNode> RHandle;
267
268 private:
269
270         PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
271
272 public:
273
274         virtual ValueBase operator()(Time t)const;
275
276         virtual String get_name()const;
277
278         virtual String get_local_name()const;
279
280         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
281
282         static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
283
284 protected:
285         virtual void get_times_vfunc(Node::time_set &/*set*/) const {}
286 }; // END of class PlaceholderValueNode
287
288
289 /*!     \class LinkableValueNode
290 **      \brief Specialized Class of Value Nodes that has links to other
291 ** Value Nodes
292 *
293 *       This Value Node is calculated based on a math calculation or a time
294 *       evaluation of the linked Value Nodes. It is commonly known as
295 *       Converted Value Nodes. The derived clases defines the behavior.
296 */
297 class LinkableValueNode : public ValueNode
298 {
299         friend class ValueNode;
300 public:
301
302         typedef etl::handle<LinkableValueNode> Handle;
303
304         typedef etl::loose_handle<LinkableValueNode> LooseHandle;
305
306         typedef etl::handle<const LinkableValueNode> ConstHandle;
307
308         typedef etl::rhandle<LinkableValueNode> RHandle;
309
310
311         //! Type that represents a pointer to a ValueNode's constructor
312         /*! As a pointer to the constructor, it represents a "factory" of
313         **  objects of this class.
314         */
315         typedef LinkableValueNode* (*Factory)(const ValueBase&);
316
317         //! This represents a pointer to a Type check member fucntion
318         /*! As a pointer to the member, it represents a fucntion that checks
319         **  the type of the provided ValueBase
320         */
321         typedef bool (*CheckType)(ValueBase::Type);
322
323         struct BookEntry
324         {
325                 String local_name;
326                 Factory factory;
327                 CheckType check_type;
328                 ReleaseVersion release_version; // which version of synfig introduced this valuenode type
329         };
330
331         //! Book of types of linkable value nodes indexed by type name.
332         /*! While the sifz file is read, each time a new LinkableValueNode entry
333         **  is found, the factory constructor that the "factory" pointer member
334         **  of the "BookEntry" struct points to, is called, and a new object of
335         **  that type is created.
336         **  \sa LinkableValueNode::Factory
337         */
338         typedef std::map<String,BookEntry> Book;
339
340         //! The vocabulary of the children
341         /*! \see synfig::Paramdesc
342          */
343         typedef ParamVocab Vocab;
344
345         static Book& book();
346
347         //! Creates a Linkable Value Node based on the name and the returned
348         //! value type. Returns a valid Handle if both (name and type) match
349         static Handle create(const String &name, const ValueBase& x);
350
351         //! Each derived Linkable Value Node has to implement this fucntion and
352         //! should return true only if the type matches. \name is the name of
353         //! the linked value node and \x is the returned value type
354         static bool check_type(const String &name, ValueBase::Type x);
355
356 public:
357         LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
358                 ValueNode(type) { }
359
360 protected:
361         //! Stores the Value Node \x in the sub parameter i after check if the
362         //! type is the same.
363         //! It has to be defined by the derived class.
364         virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
365
366         //! Frees all the subparameters of the Linkable Value Node.
367         //! Used by the derived classed destructors.
368         void unlink_all();
369
370 public:
371
372         //! Returns the number of linked Value Nodes
373         virtual int link_count()const=0;
374
375         //! Returns the local name of the 'i' linked Value Node
376         virtual String link_local_name(int i)const;
377
378         //! Returns the name of the 'i' linked Value Node
379         virtual String link_name(int i)const;
380
381         //! Returns the child index Value Node based on the name
382         virtual int get_link_index_from_name(const String &name)const;
383
384         //! Clones a Value Node
385         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
386
387         //! Sets a new Value Node link by its index
388         bool set_link(int i,ValueNode::Handle x);
389         //! Sets a new Value Node link by its name
390         bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x);      }
391
392         //! Returns a Loose Handle to the Value Node based on the link's index
393         ValueNode::LooseHandle get_link(int i)const;
394         //! Returns a Loose Handle to the Value Node based on the link's name
395         ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
396         //! Return a full description of the linked ValueNode given by the index
397         String get_description(int index = -1, bool show_exported_name = true)const;
398
399         //! Gets the parameter vocabulary for linkable value nodes
400         virtual Vocab get_param_vocab()const=0;
401
402 protected:
403         //! Sets the type of the ValueNode
404         void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
405
406         //! Virtual member to get the linked Value Node Handle
407         virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
408
409         //! Wrapper for new operator, used by clone()
410         virtual LinkableValueNode* create_new()const=0;
411
412         //! Returns the cached times values for all the children (linked Value Nodes)
413         virtual void get_times_vfunc(Node::time_set &set) const;
414 }; // END of class LinkableValueNode
415
416 /*!     \class ValueNodeList
417 **      \brief A searchable value_node list container
418 **      \warning Do not confuse with ValueNode_DynamicList!
419 *
420 *  Used by Canvas class to access to the exported value nodes.
421 */
422 class ValueNodeList : public std::list<ValueNode::RHandle>
423 {
424         int placeholder_count_;
425 public:
426         ValueNodeList();
427
428         //! Finds the ValueNode in the list with the given \a name
429         /*!     \return If found, returns a handle to the ValueNode.
430         **              Otherwise, returns an empty handle.
431         */
432         ValueNode::Handle find(const String &name);
433
434         //! Finds the ValueNode in the list with the given \a name
435         /*!     \return If found, returns a handle to the ValueNode.
436         **              Otherwise, returns an empty handle.
437         */
438         ValueNode::ConstHandle find(const String &name)const;
439
440         //! Removes the \a value_node from the list
441         bool erase(ValueNode::Handle value_node);
442
443         //! \writeme
444         bool add(ValueNode::Handle value_node);
445
446         //! \writeme
447         bool count(const String &id)const;
448
449         //! Similar to find, but will create a placeholder value_node if it cannot be found.
450         ValueNode::Handle surefind(const String &name);
451
452         //! Removes any value_nodes with reference counts of 1.
453         void audit();
454
455         //! Placeholder Count
456         int placeholder_count()const { return placeholder_count_; }
457 };
458
459 ValueNode::LooseHandle find_value_node(const GUID& guid);
460
461 }; // END of namespace synfig
462
463 /* === E N D =============================================================== */
464
465 #endif