f844f9dd44af41afe4680517e95e86f209bfef1c
[synfig.git] / synfig-core / trunk / 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 **
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 /* === S T A R T =========================================================== */
24
25 #ifndef __SYNFIG_VALUENODE_H
26 #define __SYNFIG_VALUENODE_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include "vector.h"
31 #include "value.h"
32 #include "string.h"
33 #include "releases.h"
34 #include <ETL/handle>
35 #include <ETL/stringf>
36 #include "exception.h"
37 #include <map>
38 #include <sigc++/signal.h>
39 #include "guid.h"
40
41 #ifndef SYNFIG_NO_ANGLE
42 #include <ETL/angle>
43 #endif
44
45 #include "node.h"
46
47 #include <set>
48
49 /* === M A C R O S ========================================================= */
50
51 // This is a hack for GCC 3.0.4... which has a broken dynamic_cast<>
52 // It is deprecated, and will be removed soon.
53 #if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
54 # define DCAST_HACK_BASECLASS() int cast__
55 # define DCAST_HACK_ID(x)               static const int my_cast__(void) { return x; }
56 # define DCAST_HACK_ENABLE()    cast__=my_cast__()
57 #else
58 # define DCAST_HACK_BASECLASS()
59 # define DCAST_HACK_ID(x)
60 # define DCAST_HACK_ENABLE()
61 #endif
62
63 #define CHECK_TYPE_AND_SET_VALUE(variable, type)                                                \
64         /* I don't think this ever happens - maybe remove this code? */         \
65         if (get_type() == ValueBase::TYPE_NIL) {                                                        \
66                 warning("%s:%d get_type() IS nil sometimes!",                                   \
67                                 __FILE__, __LINE__);                                                                    \
68                 return false;                                                                                                   \
69         }                                                                                                                                       \
70         if (get_type() != ValueBase::TYPE_NIL &&                                                        \
71                 !(ValueBase::same_type_as(value->get_type(), type)) &&                  \
72                 !PlaceholderValueNode::Handle::cast_dynamic(value)) {                   \
73                 error(_("%s:%d wrong type for %s: need %s but got %s"),                 \
74                           __FILE__, __LINE__,                                                                           \
75                           link_local_name(i).c_str(),                                                           \
76                           ValueBase::type_local_name(type).c_str(),                                     \
77                           ValueBase::type_local_name(value->get_type()).c_str());       \
78                 return false;                                                                                                   \
79         }                                                                                                                                       \
80         variable = value;                                                                                                       \
81         signal_child_changed()(i);                                                                                      \
82         signal_value_changed()();                                                                                       \
83         return true
84
85 /* === T Y P E D E F S ===================================================== */
86
87 /* === C L A S S E S & S T R U C T S ======================================= */
88
89 namespace synfig {
90
91 class Canvas;
92 class LinkableValueNode;
93 class Layer;
94
95 /*!     \class ValueNode
96 **      \todo writeme
97 */
98 class ValueNode : public synfig::Node
99 {
100         friend class Layer;
101         friend class LinkableValueNode;
102
103         /*
104  --     ** -- T Y P E S -----------------------------------------------------------
105         */
106
107 public:
108
109         typedef etl::handle<ValueNode> Handle;
110
111         typedef etl::loose_handle<ValueNode> LooseHandle;
112
113         typedef etl::handle<const ValueNode> ConstHandle;
114
115         typedef etl::rhandle<ValueNode> RHandle;
116
117
118         static bool subsys_init();
119
120         static bool subsys_stop();
121
122         /*
123  --     ** -- D A T A -------------------------------------------------------------
124         */
125
126 private:
127         ValueBase::Type type;
128         String name;
129         etl::loose_handle<Canvas> canvas_;
130         etl::loose_handle<Canvas> root_canvas_;
131
132         /*
133  -- ** -- S I G N A L S -------------------------------------------------------
134         */
135
136 private:
137
138         //!     ValueBase Changed
139         sigc::signal<void> signal_value_changed_;
140
141         //!     Children Reordered
142         sigc::signal<void,int*> signal_children_reordered_;
143
144         //!     Child Changed
145         sigc::signal<void,int> signal_child_changed_;
146
147         //!     Child Removed
148         sigc::signal<void,int> signal_child_removed_;
149
150         //!     Child Inserted
151         sigc::signal<void,int> signal_child_inserted_;
152
153         //!     ID Changed
154         sigc::signal<void> signal_id_changed_;
155
156         /*
157  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
158         */
159
160 public:
161
162         //!     ValueBase Changed
163         sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
164
165         //!     Children Reordered
166         sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
167
168         //!     Child Changed
169         sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
170
171         //!     Child Removed
172         sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
173
174         //!     Child Inserted
175         sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
176
177         //!     ID Changed
178         sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
179
180         /*
181  --     ** -- C O N S T R U C T O R S ---------------------------------------------
182         */
183
184 protected:
185
186         ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
187
188 public:
189
190         virtual ~ValueNode();
191
192         /*
193  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
194         */
195
196 public:
197
198         //! Returns the value of the ValueNode at time \a t
199         virtual ValueBase operator()(Time /*t*/)const
200                 { return ValueBase(); }
201
202         //! \internal Sets the id of the ValueNode
203         void set_id(const String &x);
204
205         //! Returns the id of the ValueNode
206         /*!     The ID is used for keeping track of a
207         **      specific instance of a ValueNode. */
208         const String &get_id()const { return name; }
209
210         //! Returns the name of the ValueNode type
211         virtual String get_name()const=0;
212
213         //! Returns the localized name of the ValueNode type
214         virtual String get_local_name()const=0;
215
216         //! Return a full description of the ValueNode and its parentage
217         virtual String get_description(bool show_exported_name = true)const;
218
219
220         //! \writeme
221         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
222
223         //! \writeme
224         bool is_exported()const { return !get_id().empty(); }
225
226         //! Returns the type of the ValueNode
227         ValueBase::Type get_type()const { return type; }
228
229         //! Returns a handle to the parent canvas, if it has one.
230         etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
231
232         //! Returns a handle to the parent canvas, if it has one.
233         etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
234
235         //! \writeme
236         void set_parent_canvas(etl::loose_handle<Canvas> x);
237
238         //! \writeme
239         void set_root_canvas(etl::loose_handle<Canvas> x);
240
241         //! \writeme
242         String get_relative_id(etl::loose_handle<const Canvas> x)const;
243
244         int replace(etl::handle<ValueNode> x);
245
246 protected:
247         //! Sets the type of the ValueNode
248         void set_type(ValueBase::Type t) { type=t; }
249
250         virtual void on_changed();
251
252 public:
253         DCAST_HACK_BASECLASS();
254         DCAST_HACK_ID(0);
255 }; // END of class ValueNode
256
257 /*!     \class PlaceholderValueNode
258 **      \todo writeme
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 **      \todo writeme
291 */
292 class LinkableValueNode : public ValueNode
293 {
294         friend class ValueNode;
295 public:
296
297         typedef etl::handle<LinkableValueNode> Handle;
298
299         typedef etl::loose_handle<LinkableValueNode> LooseHandle;
300
301         typedef etl::handle<const LinkableValueNode> ConstHandle;
302
303         typedef etl::rhandle<LinkableValueNode> RHandle;
304
305
306         //! Type that represents a pointer to a ValueNode's constructor
307         typedef LinkableValueNode* (*Factory)(const ValueBase&);
308
309         typedef bool (*CheckType)(ValueBase::Type);
310
311         struct BookEntry
312         {
313                 String local_name;
314                 Factory factory;
315                 CheckType check_type;
316                 ReleaseVersion release_version; // which version of synfig introduced this valuenode type
317         };
318
319         typedef std::map<String,BookEntry> Book;
320
321         static Book& book();
322
323         static Handle create(const String &name, const ValueBase& x);
324
325         static bool check_type(const String &name, ValueBase::Type x);
326
327 public:
328         LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
329                 ValueNode(type) { }
330
331 protected:
332         virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
333
334         void unlink_all();
335
336 public:
337
338         virtual int link_count()const=0;
339
340         virtual String link_local_name(int i)const=0;
341
342         virtual String link_name(int i)const=0;
343
344         virtual int get_link_index_from_name(const String &name)const=0;
345
346         virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
347
348         bool set_link(int i,ValueNode::Handle x);
349         bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x);      }
350
351         ValueNode::LooseHandle get_link(int i)const;
352         ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
353
354         String
355         get_description(int index, bool show_exported_name = true)const;
356
357 protected:
358         //! Sets the type of the ValueNode
359         void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
360
361         virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
362
363         // Wrapper for new operator, used by clone()
364         virtual LinkableValueNode* create_new()const=0;
365
366         virtual void get_times_vfunc(Node::time_set &set) const;
367 }; // END of class LinkableValueNode
368
369 /*!     \class ValueNodeList
370 **      \brief A searchable value_node list container
371 **      \warning Do not confuse with ValueNode_DynamicList!
372 **      \todo writeme
373 */
374 class ValueNodeList : public std::list<ValueNode::RHandle>
375 {
376         int placeholder_count_;
377 public:
378         ValueNodeList();
379
380         //! Finds the ValueNode in the list with the given \a name
381         /*!     \return If found, returns a handle to the ValueNode.
382         **              Otherwise, returns an empty handle.
383         */
384         ValueNode::Handle find(const String &name);
385
386         //! Finds the ValueNode in the list with the given \a name
387         /*!     \return If found, returns a handle to the ValueNode.
388         **              Otherwise, returns an empty handle.
389         */
390         ValueNode::ConstHandle find(const String &name)const;
391
392         //! Removes the \a value_node from the list
393         bool erase(ValueNode::Handle value_node);
394
395         //! \writeme
396         bool add(ValueNode::Handle value_node);
397
398         //! \writeme
399         bool count(const String &id)const;
400
401         //! Similar to find, but will create a placeholder value_node if it cannot be found.
402         ValueNode::Handle surefind(const String &name);
403
404         //! Removes any value_nodes with reference counts of 1.
405         void audit();
406
407         //! Placeholder Count
408         int placeholder_count()const { return placeholder_count_; }
409 };
410
411 ValueNode::LooseHandle find_value_node(const GUID& guid);
412
413 }; // END of namespace synfig
414
415 /* === E N D =============================================================== */
416
417 #endif