Documentation
[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
43 #include "node.h"
44
45 #include <set>
46
47 /* === M A C R O S ========================================================= */
48
49 #define CHECK_TYPE_AND_SET_VALUE(variable, type)                                                \
50         /* I don't think this ever happens - maybe remove this code? */         \
51         if (get_type() == ValueBase::TYPE_NIL) {                                                        \
52                 warning("%s:%d get_type() IS nil sometimes!",                                   \
53                                 __FILE__, __LINE__);                                                                    \
54                 return false;                                                                                                   \
55         }                                                                                                                                       \
56         if (get_type() != ValueBase::TYPE_NIL &&                                                        \
57                 !(ValueBase::same_type_as(value->get_type(), type)) &&                  \
58                 !PlaceholderValueNode::Handle::cast_dynamic(value)) {                   \
59                 error(_("%s:%d wrong type for %s: need %s but got %s"),                 \
60                           __FILE__, __LINE__,                                                                           \
61                           link_local_name(i).c_str(),                                                           \
62                           ValueBase::type_local_name(type).c_str(),                                     \
63                           ValueBase::type_local_name(value->get_type()).c_str());       \
64                 return false;                                                                                                   \
65         }                                                                                                                                       \
66         variable = value;                                                                                                       \
67         signal_child_changed()(i);                                                                                      \
68         signal_value_changed()();                                                                                       \
69         return true
70
71 /* === T Y P E D E F S ===================================================== */
72
73 /* === C L A S S E S & S T R U C T S ======================================= */
74
75 namespace synfig {
76
77 class Canvas;
78 class LinkableValueNode;
79 class Layer;
80
81 /*!     \class ValueNode
82 **      \brief Base class for all Value Nodes
83 */
84 class ValueNode : public synfig::Node
85 {
86         friend class Layer;
87         friend class LinkableValueNode;
88
89         /*
90  --     ** -- T Y P E S -----------------------------------------------------------
91         */
92
93 public:
94
95         typedef etl::handle<ValueNode> Handle;
96
97         typedef etl::loose_handle<ValueNode> LooseHandle;
98
99         typedef etl::handle<const ValueNode> ConstHandle;
100
101         typedef etl::rhandle<ValueNode> RHandle;
102
103         //!Instantiates the book of ValaueNodes and register all the valid valuenodes on it
104         static bool subsys_init();
105         //!Deletes the book of ValueNodes
106         static bool subsys_stop();
107
108         /*
109  --     ** -- D A T A -------------------------------------------------------------
110         */
111
112 private:
113         ValueBase::Type type;
114         String name;
115         etl::loose_handle<Canvas> canvas_;
116         etl::loose_handle<Canvas> root_canvas_;
117
118         /*
119  -- ** -- S I G N A L S -------------------------------------------------------
120         */
121
122 private:
123
124         //!     ValueBase Changed
125         sigc::signal<void> signal_value_changed_;
126
127         //!     Children Reordered
128         sigc::signal<void,int*> signal_children_reordered_;
129
130         //!     Child Changed
131         sigc::signal<void,int> signal_child_changed_;
132
133         //!     Child Removed
134         sigc::signal<void,int> signal_child_removed_;
135
136         //!     Child Inserted
137         sigc::signal<void,int> signal_child_inserted_;
138
139         //!     ID Changed
140         sigc::signal<void> signal_id_changed_;
141
142         /*
143  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
144         */
145
146 public:
147
148         //!     ValueBase Changed
149         sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
150
151         //!     Children Reordered
152         sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
153
154         //!     Child Changed
155         sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
156
157         //!     Child Removed
158         sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
159
160         //!     Child Inserted
161         sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
162
163         //!     ID Changed
164         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
165
166         /*
167  --     ** -- C O N S T R U C T O R S ---------------------------------------------
168         */
169
170 protected:
171
172         ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
173
174 public:
175
176         virtual ~ValueNode();
177
178         /*
179  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
180         */
181
182 public:
183
184         //! Returns the value of the ValueNode at time \a t
185         virtual ValueBase operator()(Time /*t*/)const
186                 { return ValueBase(); }
187
188         //! \internal Sets the id of the ValueNode
189         void set_id(const String &x);
190
191         //! Returns the id of the ValueNode
192         /*!     The ID is used for keeping track of a
193         **      specific instance of a ValueNode. */
194         const String &get_id()const { return name; }
195
196         //! Returns the name of the ValueNode type
197         virtual String get_name()const=0;
198
199         //! Returns the localized name of the ValueNode type
200         virtual String get_local_name()const=0;
201
202         //! Return a full description of the ValueNode and its parentage
203         virtual String get_description(bool show_exported_name = true)const;
204
205
206         //! Clones a Value Node
207         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
208
209         //! Returns \true if the Value Node has an ID (has been exported)
210         bool is_exported()const { return !get_id().empty(); }
211
212         //! Returns the type of the ValueNode
213         ValueBase::Type get_type()const { return type; }
214
215         //! Returns a handle to the parent canvas, if it has one.
216         etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
217
218         //! Returns a handle to the parent canvas, if it has one.
219         etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
220
221         //! Sets the parent canvas for the Value Node
222         void set_parent_canvas(etl::loose_handle<Canvas> x);
223
224         //! Sets the root canvas parent for the Value Node
225         void set_root_canvas(etl::loose_handle<Canvas> x);
226
227         //! Returns the relative ID of a Node when accessed form the \x Canvas
228         String get_relative_id(etl::loose_handle<const Canvas> x)const;
229
230         //! Replaces the Value Node with a given one. It look up all its parents
231         //! remove it self from them and adds the given Value Node
232         //! Notice that it is called twice and the second time it uses
233         //! a replaceable handle to the Node
234         //! \see etl::rhandle
235         int replace(etl::handle<ValueNode> x);
236
237 protected:
238         //! Sets the type of the ValueNode
239         void set_type(ValueBase::Type t) { type=t; }
240
241         virtual void on_changed();
242 }; // END of class ValueNode
243
244 /*!     \class PlaceholderValueNode
245 **      \todo writeme
246 */
247 class PlaceholderValueNode : public ValueNode
248 {
249 public:
250         typedef etl::handle<PlaceholderValueNode> Handle;
251         typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
252         typedef etl::handle<const PlaceholderValueNode> ConstHandle;
253         typedef etl::rhandle<PlaceholderValueNode> RHandle;
254
255 private:
256
257         PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
258
259 public:
260
261         virtual ValueBase operator()(Time t)const;
262
263         virtual String get_name()const;
264
265         virtual String get_local_name()const;
266
267         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
268
269         static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
270
271 protected:
272         virtual void get_times_vfunc(Node::time_set &/*set*/) const {}
273 }; // END of class PlaceholderValueNode
274
275
276 /*!     \class LinkableValueNode
277 **      \brief Specialized Class of Value Nodes that has links to other
278 ** Value Nodes
279 *
280 *       This Value Node is calculated based on a math calculation or a time
281 *       evaluation of the linked Value Nodes. It is commonly known as
282 *       Converted Value Nodes. The derived clases defines the behavior.
283 */
284 class LinkableValueNode : public ValueNode
285 {
286         friend class ValueNode;
287 public:
288
289         typedef etl::handle<LinkableValueNode> Handle;
290
291         typedef etl::loose_handle<LinkableValueNode> LooseHandle;
292
293         typedef etl::handle<const LinkableValueNode> ConstHandle;
294
295         typedef etl::rhandle<LinkableValueNode> RHandle;
296
297
298         //! Type that represents a pointer to a ValueNode's constructor
299         /*! As a pointer to the constructor, it represents a "factory" of
300         **  objects of this class.
301         */
302         typedef LinkableValueNode* (*Factory)(const ValueBase&);
303
304         //! This represents a pointer to a Type check member fucntion
305         /*! As a pointer to the member, it represents a fucntion that checks
306         **  the type of the provided ValueBase
307         */
308         typedef bool (*CheckType)(ValueBase::Type);
309
310         struct BookEntry
311         {
312                 String local_name;
313                 Factory factory;
314                 CheckType check_type;
315                 ReleaseVersion release_version; // which version of synfig introduced this valuenode type
316         };
317
318         //! Book of types of linkable value nodes indexed by type name.
319         /*! While the sifz file is read, each time a new LinkableValueNode entry
320         **  is found, the factory constructor that the "factory" pointer member
321         **  of the "BookEntry" struct points to, is called, and a new object of
322         **  that type is created.
323         **  \sa LinkableValueNode::Factory
324         */
325         typedef std::map<String,BookEntry> Book;
326
327         static Book& book();
328
329         static Handle create(const String &name, const ValueBase& x);
330
331         static bool check_type(const String &name, ValueBase::Type x);
332
333 public:
334         LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
335                 ValueNode(type) { }
336
337 protected:
338         virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
339
340         void unlink_all();
341
342 public:
343
344         //! Returns the number of linked Value Nodes
345         virtual int link_count()const=0;
346
347         //! Returns the local name of the 'i' linked Value Node
348         virtual String link_local_name(int i)const=0;
349
350         //! Returns the name of the 'i' linked Value Node
351         virtual String link_name(int i)const=0;
352
353         //! Returns the child index Value Node based on the name
354         virtual int get_link_index_from_name(const String &name)const=0;
355
356         //! Clones a Value Node
357         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
358
359         //! Sets a new Value Node link by its index
360         bool set_link(int i,ValueNode::Handle x);
361         //! Sets a new Value Node link by its name
362         bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x);      }
363
364         //! Returns a Loose Handle to the Value Node based on the link's index
365         ValueNode::LooseHandle get_link(int i)const;
366         //! Returns a Loose Handle to the Value Node based on the link's name
367         ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
368         //! Return a full description of the linked ValueNode given by the index
369         String get_description(int index = -1, bool show_exported_name = true)const;
370
371 protected:
372         //! Sets the type of the ValueNode
373         void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
374
375         //! Virtual member to get the linked Value Node Handle
376         virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
377
378         //! Wrapper for new operator, used by clone()
379         virtual LinkableValueNode* create_new()const=0;
380
381         //! Returns the cached times values for all the children (linked Value Nodes)
382         virtual void get_times_vfunc(Node::time_set &set) const;
383 }; // END of class LinkableValueNode
384
385 /*!     \class ValueNodeList
386 **      \brief A searchable value_node list container
387 **      \warning Do not confuse with ValueNode_DynamicList!
388 *
389 *  Used by Canvas class to access to the exported value nodes.
390 */
391 class ValueNodeList : public std::list<ValueNode::RHandle>
392 {
393         int placeholder_count_;
394 public:
395         ValueNodeList();
396
397         //! Finds the ValueNode in the list with the given \a name
398         /*!     \return If found, returns a handle to the ValueNode.
399         **              Otherwise, returns an empty handle.
400         */
401         ValueNode::Handle find(const String &name);
402
403         //! Finds the ValueNode in the list with the given \a name
404         /*!     \return If found, returns a handle to the ValueNode.
405         **              Otherwise, returns an empty handle.
406         */
407         ValueNode::ConstHandle find(const String &name)const;
408
409         //! Removes the \a value_node from the list
410         bool erase(ValueNode::Handle value_node);
411
412         //! \writeme
413         bool add(ValueNode::Handle value_node);
414
415         //! \writeme
416         bool count(const String &id)const;
417
418         //! Similar to find, but will create a placeholder value_node if it cannot be found.
419         ValueNode::Handle surefind(const String &name);
420
421         //! Removes any value_nodes with reference counts of 1.
422         void audit();
423
424         //! Placeholder Count
425         int placeholder_count()const { return placeholder_count_; }
426 };
427
428 ValueNode::LooseHandle find_value_node(const GUID& guid);
429
430 }; // END of namespace synfig
431
432 /* === E N D =============================================================== */
433
434 #endif