More documentation
[synfig.git] / synfig-core / src / synfig / node.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file node.h
3 **      \brief Base class for Layers and Value Nodes.
4 **      It defines the base members for the parent - child relationship,
5 **      the times where the node is modified and the handling of
6 **      the GUID on deletion and changing.
7 **
8 **      $Id$
9 **
10 **      \legal
11 **      Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
12 **      Copyright (c) 2007 Chris Moore
13 **
14 **      This package is free software; you can redistribute it and/or
15 **      modify it under the terms of the GNU General Public License as
16 **      published by the Free Software Foundation; either version 2 of
17 **      the License, or (at your option) any later version.
18 **
19 **      This package is distributed in the hope that it will be useful,
20 **      but WITHOUT ANY WARRANTY; without even the implied warranty of
21 **      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 **      General Public License for more details.
23 **      \endlegal
24 */
25 /* ========================================================================= */
26
27 /* === S T A R T =========================================================== */
28
29 #ifndef __SYNFIG_PARENTNODE_H
30 #define __SYNFIG_PARENTNODE_H
31
32 /* === H E A D E R S ======================================================= */
33
34 #include <sigc++/signal.h>
35 #include <set>
36 #include "time.h"
37 #include "guid.h"
38 #include <ETL/handle>
39 #include "interpolation.h"
40 #include "mutex.h"
41
42 /* === M A C R O S ========================================================= */
43
44 // When a PasteCanvas layer has a non-zero 'time offset' parameter, should
45 // the waypoints shown for the canvas be adjusted?  This currently only
46 // partially works - see the TODO at the end of layer_pastecanvas.cpp
47 #define ADJUST_WAYPOINTS_FOR_TIME_OFFSET
48
49 /* === T Y P E D E F S ===================================================== */
50
51 /* === C L A S S E S & S T R U C T S ======================================= */
52
53 namespace synfig {
54
55 //!\brief TimePoint class: holds the time and the before and after interpolation mode
56 /**
57  * It includes a GUID, to make it unique
58  * \see guid.h interpolation.h
59 **/
60 class TimePoint
61 {
62         GUID guid;
63         Time time;
64         Interpolation before,after;
65 public:
66
67         TimePoint(const Time& x=Time::begin()):
68                 guid(0),
69                 time(x),
70                 before(INTERPOLATION_NIL),
71                 after(INTERPOLATION_NIL)
72         {
73         }
74
75 #ifdef _DEBUG
76         const char *c_str()const;
77 #endif
78
79         const GUID& get_guid()const { return guid; }
80         const Time& get_time()const { return time; }
81         Interpolation get_before()const { return before; }
82         Interpolation get_after()const { return after; }
83
84         void set_guid(const GUID& x) { guid=x; }
85         void set_time(const Time& x) { time=x; }
86         void set_before(Interpolation x) { before=x; }
87         void set_after(Interpolation x) { after=x; }
88
89         //! Modify the TimePoint based on the values of \x "merging"
90         //! the interpolations. Used to insert a Time Point in a Time Points Set
91         //! \see TimePointSet::iterator TimePointSet::insert(const TimePoint& x)
92         void absorb(const TimePoint& x);
93 }; // END of class TimePoint
94
95 inline TimePoint operator+(TimePoint lhs,const Time& rhs)
96         { lhs.set_time(lhs.get_time()+rhs); return lhs; }
97
98 inline TimePoint operator-(TimePoint lhs,const Time& rhs)
99         { lhs.set_time(lhs.get_time()-rhs); return lhs; }
100
101 inline bool operator<(const TimePoint& lhs,const TimePoint& rhs)
102         { return lhs.get_time()<rhs.get_time(); }
103
104 inline bool operator<(const TimePoint& lhs,const Time& rhs)
105         { return lhs.get_time()<rhs; }
106
107 inline bool operator<(const Time& lhs,const TimePoint& rhs)
108         { return lhs<rhs.get_time(); }
109
110 inline bool operator==(const TimePoint& lhs,const TimePoint& rhs)
111         { return lhs.get_time()==rhs.get_time(); }
112
113 inline bool operator!=(const TimePoint& lhs,const TimePoint& rhs)
114         { return lhs.get_time()!=rhs.get_time(); }
115
116 class TimePointSet : public std::set<TimePoint>
117 {
118 public:
119         iterator insert(const TimePoint& x);
120
121         template <typename ITER> void insert(ITER begin, ITER end)
122                 { for(;begin!=end;++begin) insert(*begin); }
123
124 }; // END of class TimePointSet
125
126 class Node : public etl::rshared_object
127 {
128         /*
129  --     ** -- T Y P E S -----------------------------------------------------------
130         */
131
132 public:
133
134         //! \writeme
135         typedef TimePointSet    time_set;
136
137         /*
138  --     ** -- D A T A -------------------------------------------------------------
139         */
140
141 private:
142
143         //! \ The GUID of the node
144         GUID guid_;
145
146         //! cached time values for all the children
147         mutable time_set        times;
148
149         //! \writeme
150         mutable bool            bchanged;
151
152         //! The last time the node was modified since the program started
153         //! \see __sys_clock
154         mutable int time_last_changed_;
155
156         //! \writeme
157         //! \see mutex.h
158         mutable RWLock rw_lock_;
159
160         //! Variable used to remember that a signal_deleted has been thrown
161         bool deleting_;
162
163 public:
164
165         //! A set of pointers to parent nodes
166         //! \todo This should really be private
167         std::set<Node*>         parent_set;
168
169         /*
170  -- ** -- S I G N A L S -------------------------------------------------------
171         */
172
173 private:
174
175         //! Node changed signal
176         sigc::signal<void> signal_changed_;
177
178         //!     GUID changed signal
179         /*! \note The second parameter is the *OLD* guid! */
180         sigc::signal<void,GUID> signal_guid_changed_;
181
182         //!     Node deleted signal
183         sigc::signal<void> signal_deleted_;
184
185         /*
186  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
187         */
188
189 public:
190
191         sigc::signal<void>& signal_deleted() { return signal_deleted_; }
192
193         sigc::signal<void>& signal_changed() { return signal_changed_; }
194
195         //!     GUID Changed
196         /*! \note The second parameter is the *OLD* guid! */
197         sigc::signal<void,GUID>& signal_guid_changed() { return signal_guid_changed_; }
198
199         /*
200  --     ** -- C O N S T R U C T O R S ---------------------------------------------
201         */
202
203 protected:
204
205         Node();
206
207         // This class cannot be copied -- use clone() if necessary
208 private:
209         Node(const Node &x);
210
211 public:
212         virtual ~Node();
213
214         /*
215  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
216         */
217
218 public:
219
220         void changed();
221
222         //! Gets the GUID for this Node
223         const GUID& get_guid()const;
224
225         //! Sets the GUID for this Node
226         void set_guid(const GUID& x);
227
228         //! Gets the time when the Node was changed
229         int get_time_last_changed()const;
230
231         //! Adds the parameter \x as the child of the current Node
232         void add_child(Node*x);
233
234         //! Removes the parameter \x as a child of the current Node
235         void remove_child(Node*x);
236
237         //!Returns how many parenst has the current Node
238         int parent_count()const;
239
240         //! Returns the cached times values for all the children
241         const time_set &get_times() const;
242
243         //! Writeme!
244         RWLock& get_rw_lock()const { return rw_lock_; }
245
246 protected:
247
248         void begin_delete();
249
250         /*
251  --     ** -- V I R T U A L   F U N C T I O N S -----------------------------------
252         */
253
254 protected:
255         //! Used when the node has changed. Makes changed the parent too.
256         //! To be overloaded by the derivative classes. Emits a signal where the
257         //! the GUI can be connected to.
258         virtual void on_changed();
259
260         //! Used when the node's GUID has changed.
261         //! To be overloaded by the derivative classes. Emits a signal where the
262         //! the GUI can be connected to.
263         virtual void on_guid_changed(GUID guid);
264
265         //!     Function to be overloaded that fills the Time Point Set with
266         //! all the children Time Points.
267         virtual void get_times_vfunc(time_set &set) const = 0;
268 }; // End of Node class
269
270 //! Finds a node by its GUID.
271 //! \see global_node_map()
272 synfig::Node* find_node(const synfig::GUID& guid);
273
274 //! Returns a Handle to the Node by its GUID
275 template<typename T> etl::handle<T>
276 guid_cast(const synfig::GUID& guid)
277 {
278         return etl::handle<T>::cast_dynamic(synfig::find_node(guid));
279 }
280
281 #ifdef _DEBUG
282 template <typename T>
283 synfig::String set_string(T start, T end)
284 {
285         synfig::String ret("[");
286         bool started = false;
287
288         while (start != end)
289         {
290                 if (started)    ret += ", ";
291                 else                    started = true;
292
293                 ret += synfig::String((*start).c_str());
294                 start++;
295         }
296
297         return ret + "]";
298 }
299
300 template <typename T>
301 synfig::String set_string(T set)
302 {
303         return set_string(set.begin(), set.end());
304 }
305 #endif // _DEBUG
306
307 typedef etl::handle<Node> NodeHandle;
308
309 }; // END of namespace synfig
310
311 /* === E N D =============================================================== */
312
313 #endif