moreupdates
[synfig.git] / synfig-core / trunk / src / synfig / valuenode.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file valuenode.h
3 **      \brief Template Header
4 **
5 **      $Id: valuenode.h,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
6 **
7 **      \legal
8 **      Copyright (c) 2002 Robert B. Quattlebaum Jr.
9 **
10 **      This software and associated documentation
11 **      are CONFIDENTIAL and PROPRIETARY property of
12 **      the above-mentioned copyright holder.
13 **
14 **      You may not copy, print, publish, or in any
15 **      other way distribute this software without
16 **      a prior written agreement with
17 **      the copyright holder.
18 **      \endlegal
19 */
20 /* ========================================================================= */
21
22 /* === S T A R T =========================================================== */
23
24 #ifndef __SYNFIG_VALUENODE_H
25 #define __SYNFIG_VALUENODE_H
26
27 /* === H E A D E R S ======================================================= */
28
29 #include "vector.h"
30 #include "value.h"
31 #include "string.h"
32 #include <ETL/handle>
33 #include <ETL/stringf>
34 #include "exception.h"
35 #include <map>
36 #include <sigc++/signal.h>
37 #include "guid.h"
38
39 #ifndef SYNFIG_NO_ANGLE
40 #include <ETL/angle>
41 #endif
42
43 #include "node.h"
44
45 #include <set>
46
47 /* === M A C R O S ========================================================= */
48
49 // This is a hack for GCC 3.0.4... which has a broken dynamic_cast<>
50 // It is deprecated, and will be removed soon.
51 #if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
52 # define DCAST_HACK_BASECLASS() int cast__
53 # define DCAST_HACK_ID(x)               static const int my_cast__(void) { return x; }
54 # define DCAST_HACK_ENABLE()    cast__=my_cast__()
55 #else
56 # define DCAST_HACK_BASECLASS()
57 # define DCAST_HACK_ID(x)
58 # define DCAST_HACK_ENABLE()
59 #endif
60
61 /* === T Y P E D E F S ===================================================== */
62
63 /* === C L A S S E S & S T R U C T S ======================================= */
64
65 namespace synfig {
66
67 class Canvas;
68 class LinkableValueNode;
69 class Layer;
70         
71 /*!     \class ValueNode
72 **      \todo writeme
73 */
74 class ValueNode : public synfig::Node
75 {
76         friend class Layer;
77         friend class LinkableValueNode;
78                 
79         /*
80  --     ** -- T Y P E S -----------------------------------------------------------
81         */
82
83 public:
84
85         typedef etl::handle<ValueNode> Handle;
86
87         typedef etl::loose_handle<ValueNode> LooseHandle;
88
89         typedef etl::handle<const ValueNode> ConstHandle;
90
91         typedef etl::rhandle<ValueNode> RHandle;
92
93
94         static bool subsys_init();
95
96         static bool subsys_stop();
97
98         /*
99  --     ** -- D A T A -------------------------------------------------------------
100         */
101
102 private:
103         ValueBase::Type type;
104         String name;
105         etl::loose_handle<Canvas> canvas_;
106         etl::loose_handle<Canvas> root_canvas_;
107         
108         /*
109  -- ** -- S I G N A L S -------------------------------------------------------
110         */
111
112 private:
113
114         //!     ValueBase Changed
115         sigc::signal<void> signal_value_changed_;       
116
117         //!     Children Reordered
118         sigc::signal<void,int*> signal_children_reordered_;     
119
120         //!     Child Changed
121         sigc::signal<void,int> signal_child_changed_;   
122
123         //!     Child Removed
124         sigc::signal<void,int> signal_child_removed_;   
125
126         //!     Child Inserted
127         sigc::signal<void,int> signal_child_inserted_;  
128
129         //!     ID Changed
130         sigc::signal<void> signal_id_changed_;  
131
132         /*
133  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
134         */
135
136 public:
137
138         //!     ValueBase Changed
139         sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
140
141         //!     Children Reordered
142         sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
143
144         //!     Child Changed
145         sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
146
147         //!     Child Removed
148         sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
149
150         //!     Child Inserted
151         sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
152
153         //!     ID Changed
154         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
155
156         /*
157  --     ** -- C O N S T R U C T O R S ---------------------------------------------
158         */
159
160 protected:
161         
162         ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
163
164 public:
165
166         virtual ~ValueNode();
167
168         /*
169  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
170         */
171
172 public:
173
174         //! Returns the value of the ValueNode at time \a t
175         virtual ValueBase operator()(Time t)const
176                 { return ValueBase(); }
177
178         //! \internal Sets the id of the ValueNode
179         void set_id(const String &x);
180
181         //! Returns the id of the ValueNode
182         /*!     The ID is used for keeping track of a
183         **      specific instance of a ValueNode. */
184         const String &get_id()const { return name; }
185
186         //! Returns the name of the ValueNode type
187         virtual String get_name()const=0;
188
189         //! Returns the localized name of the ValueNode type
190         virtual String get_local_name()const=0;
191
192
193         //! \writeme
194         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
195
196         //! \writeme
197         bool is_exported()const { return !get_id().empty(); }
198         
199         //! Returns the type of the ValueNode
200         ValueBase::Type get_type()const { return type; }
201
202         //! Returns a handle to the parent canvas, if it has one.
203         etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
204
205         //! Returns a handle to the parent canvas, if it has one.
206         etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
207         
208         //! \writeme
209         void set_parent_canvas(etl::loose_handle<Canvas> x);
210
211         //! \writeme
212         void set_root_canvas(etl::loose_handle<Canvas> x);
213         
214         //! \writeme
215         String get_relative_id(etl::loose_handle<const Canvas> x)const;
216         
217         int replace(etl::handle<ValueNode> x);
218         
219 protected:
220         //! Sets the type of the ValueNode
221         void set_type(ValueBase::Type t) { type=t; }
222
223         virtual void on_changed();
224         
225 public:
226         DCAST_HACK_BASECLASS();
227         DCAST_HACK_ID(0);
228 }; // END of class ValueNode
229
230 /*!     \class PlaceholderValueNode
231 **      \todo writeme
232 */
233 class PlaceholderValueNode : public ValueNode
234 {
235 public:
236         typedef etl::handle<PlaceholderValueNode> Handle;
237         typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
238         typedef etl::handle<const PlaceholderValueNode> ConstHandle;
239         typedef etl::rhandle<PlaceholderValueNode> RHandle;
240
241 private:
242
243         PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
244
245 public:
246         
247         virtual ValueBase operator()(Time t)const;
248
249         virtual String get_name()const;
250
251         virtual String get_local_name()const;
252
253         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
254
255         static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
256
257 protected:
258         virtual void get_times_vfunc(Node::time_set &set) const {}
259 }; // END of class PlaceholderValueNode
260
261
262 /*!     \class LinkableValueNode
263 **      \todo writeme
264 */
265 class LinkableValueNode : public ValueNode
266 {
267         friend class ValueNode;
268 public:
269
270         typedef etl::handle<LinkableValueNode> Handle;
271
272         typedef etl::loose_handle<LinkableValueNode> LooseHandle;
273
274         typedef etl::handle<const LinkableValueNode> ConstHandle;
275
276         typedef etl::rhandle<LinkableValueNode> RHandle;
277
278
279         //! Type that represents a pointer to a ValueNode's constructor
280         typedef LinkableValueNode* (*Factory)(const ValueBase&);
281
282         typedef bool (*CheckType)(ValueBase::Type);
283
284         struct BookEntry
285         {
286                 String local_name;
287                 Factory factory;
288                 CheckType check_type;           
289         };
290         
291         typedef std::map<String,BookEntry> Book;
292
293         static Book& book();
294
295         static Handle create(const String &name, const ValueBase& x);
296
297         static bool check_type(const String &name, ValueBase::Type x);
298
299 public:
300         LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
301                 ValueNode(type) { }
302
303 protected:
304         virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
305
306         void unlink_all();
307
308 public:
309         
310         virtual int link_count()const=0;
311
312         virtual String link_local_name(int i)const=0;
313
314         virtual String link_name(int i)const=0;
315
316         virtual int get_link_index_from_name(const String &name)const=0;
317                 
318         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
319
320         bool set_link(int i,ValueNode::Handle x);
321         bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x);      }               
322                 
323         ValueNode::LooseHandle get_link(int i)const;
324         ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
325
326 protected:
327         //! Sets the type of the ValueNode
328         void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
329
330         virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
331
332         // Wrapper for new operator, used by clone()
333         virtual LinkableValueNode* create_new()const=0;
334         
335         virtual void get_times_vfunc(Node::time_set &set) const;
336 }; // END of class LinkableValueNode
337
338 /*!     \class ValueNodeList
339 **      \brief A searchable value_node list container
340 **      \warning Do not confuse with ValueNode_DynamicList!
341 **      \todo writeme
342 */
343 class ValueNodeList : public std::list<ValueNode::RHandle>
344 {
345         int placeholder_count_;
346 public:
347         ValueNodeList();
348
349         //! Finds the ValueNode in the list with the given \a name
350         /*!     \return If found, returns a handle to the ValueNode.
351         **              Otherwise, returns an empty handle.
352         */
353         ValueNode::Handle find(const String &name);
354
355         //! Finds the ValueNode in the list with the given \a name
356         /*!     \return If found, returns a handle to the ValueNode.
357         **              Otherwise, returns an empty handle.
358         */
359         ValueNode::ConstHandle find(const String &name)const;
360
361         //! Removes the \a value_node from the list
362         bool erase(ValueNode::Handle value_node);
363
364         //! \writeme
365         bool add(ValueNode::Handle value_node);
366
367         //! \writeme
368         bool count(const String &id)const;
369
370         //! Similar to find, but will create a placeholder value_node if it cannot be found.
371         ValueNode::Handle surefind(const String &name);
372
373         //! Removes any value_nodes with reference counts of 1.
374         void audit();
375         
376         //! Placeholder Count
377         int placeholder_count()const { return placeholder_count_; }
378 };
379
380 ValueNode::LooseHandle find_value_node(const GUID& guid);
381
382 }; // END of namespace synfig
383
384 /* === E N D =============================================================== */
385
386 #endif