85ad5ebab382f323a0988320bcc7ad970e7a8af5
[synfig.git] / synfig-core / trunk / src / synfig / node.h
1 /* === S Y N F I G ========================================================= */
2 /*!     \file node.h
3 **      \brief Template Header
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_PARENTNODE_H
26 #define __SYNFIG_PARENTNODE_H
27
28 /* === H E A D E R S ======================================================= */
29
30 #include <sigc++/signal.h>
31 #include <set>
32 #include "time.h"
33 #include "guid.h"
34 #include <ETL/handle>
35 #include "interpolation.h"
36 #include "mutex.h"
37
38 /* === M A C R O S ========================================================= */
39
40 // When a PasteCanvas layer has a non-zero 'time offset' parameter, should
41 // the waypoints shown for the canvas be adjusted?  This currently only
42 // partially works - see the TODO at the end of layer_pastecanvas.cpp
43 #define ADJUST_WAYPOINTS_FOR_TIME_OFFSET
44
45 /* === T Y P E D E F S ===================================================== */
46
47 /* === C L A S S E S & S T R U C T S ======================================= */
48
49 namespace synfig {
50
51 class TimePoint
52 {
53         GUID guid;
54         Time time;
55         Interpolation before,after;
56 public:
57
58         TimePoint(const Time& x=Time::begin()):
59                 guid(0),
60                 time(x),
61                 before(INTERPOLATION_NIL),
62                 after(INTERPOLATION_NIL)
63         {
64         }
65
66 #ifdef _DEBUG
67         const char *c_str()const;
68 #endif
69
70         const GUID& get_guid()const { return guid; }
71         const Time& get_time()const { return time; }
72         Interpolation get_before()const { return before; }
73         Interpolation get_after()const { return after; }
74
75         void set_guid(const GUID& x) { guid=x; }
76         void set_time(const Time& x) { time=x; }
77         void set_before(Interpolation x) { before=x; }
78         void set_after(Interpolation x) { after=x; }
79
80         void absorb(const TimePoint& x);
81 }; // END of class TimePoint
82
83 inline TimePoint operator+(TimePoint lhs,const Time& rhs)
84         { lhs.set_time(lhs.get_time()+rhs); return lhs; }
85
86 inline TimePoint operator-(TimePoint lhs,const Time& rhs)
87         { lhs.set_time(lhs.get_time()-rhs); return lhs; }
88
89 inline bool operator<(const TimePoint& lhs,const TimePoint& rhs)
90         { return lhs.get_time()<rhs.get_time(); }
91
92 inline bool operator<(const TimePoint& lhs,const Time& rhs)
93         { return lhs.get_time()<rhs; }
94
95 inline bool operator<(const Time& lhs,const TimePoint& rhs)
96         { return lhs<rhs.get_time(); }
97
98 inline bool operator==(const TimePoint& lhs,const TimePoint& rhs)
99         { return lhs.get_time()==rhs.get_time(); }
100
101 inline bool operator!=(const TimePoint& lhs,const TimePoint& rhs)
102         { return lhs.get_time()!=rhs.get_time(); }
103
104 class TimePointSet : public std::set<TimePoint>
105 {
106 public:
107         iterator insert(const TimePoint& x);
108
109         template <typename ITER> void insert(ITER begin, ITER end)
110                 { for(;begin!=end;++begin) insert(*begin); }
111
112 }; // END of class TimePointSet
113
114 class Node : public etl::rshared_object
115 {
116         /*
117  --     ** -- T Y P E S -----------------------------------------------------------
118         */
119
120 public:
121
122         //! \writeme
123         typedef TimePointSet    time_set;
124
125         /*
126  --     ** -- D A T A -------------------------------------------------------------
127         */
128
129 private:
130
131         //! \writeme
132         GUID guid_;
133
134         //! cached time values for all the children
135         mutable time_set        times;
136
137         //! \writeme
138         mutable bool            bchanged;
139
140         //! \writeme
141         mutable int time_last_changed_;
142
143         //! \writeme
144         mutable RWLock rw_lock_;
145
146         //! \writeme
147         bool deleting_;
148
149 public:
150
151         //! \todo This should really be private
152         std::set<Node*>         parent_set;
153
154         /*
155  -- ** -- S I G N A L S -------------------------------------------------------
156         */
157
158 private:
159
160         sigc::signal<void> signal_changed_;
161
162         //!     GUID Changed
163         /*! \note The second parameter is the *OLD* guid! */
164         sigc::signal<void,GUID> signal_guid_changed_;
165
166         //!     Deleted
167         sigc::signal<void> signal_deleted_;
168
169         /*
170  -- ** -- S I G N A L   I N T E R F A C E -------------------------------------
171         */
172
173 public:
174
175         sigc::signal<void>& signal_deleted() { return signal_deleted_; }
176
177         sigc::signal<void>& signal_changed() { return signal_changed_; }
178
179         //!     GUID Changed
180         /*! \note The second parameter is the *OLD* guid! */
181         sigc::signal<void,GUID>& signal_guid_changed() { return signal_guid_changed_; }
182
183         /*
184  --     ** -- C O N S T R U C T O R S ---------------------------------------------
185         */
186
187 protected:
188
189         Node();
190
191         // This class cannot be copied -- use clone() if necessary
192 private:
193         Node(const Node &x);
194
195 public:
196         virtual ~Node();
197
198         /*
199  --     ** -- M E M B E R   F U N C T I O N S -------------------------------------
200         */
201
202 public:
203
204         void changed();
205
206         //! Gets the GUID for this value node
207         const GUID& get_guid()const;
208
209         //! Sets the GUID for this value node
210         void set_guid(const GUID& x);
211
212         int get_time_last_changed()const;
213
214         void add_child(Node*x);
215
216         void remove_child(Node*x);
217
218         int parent_count()const;
219
220         const time_set &get_times() const;
221
222         RWLock& get_rw_lock()const { return rw_lock_; }
223
224 protected:
225
226         void begin_delete();
227
228         /*
229  --     ** -- V I R T U A L   F U N C T I O N S -----------------------------------
230         */
231
232 protected:
233         virtual void on_changed();
234
235         virtual void on_guid_changed(GUID guid);
236
237         /*!     Function to be overloaded that fills
238         */
239         virtual void get_times_vfunc(time_set &set) const = 0;
240 };
241
242 synfig::Node* find_node(const synfig::GUID& guid);
243
244 template<typename T> etl::handle<T>
245 guid_cast(const synfig::GUID& guid)
246 {
247         return etl::handle<T>::cast_dynamic(synfig::find_node(guid));
248 }
249
250 #ifdef _DEBUG
251 template <typename T>
252 synfig::String set_string(T start, T end)
253 {
254         synfig::String ret("[");
255         bool started = false;
256
257         while (start != end)
258         {
259                 if (started)    ret += ", ";
260                 else                    started = true;
261
262                 ret += synfig::String((*start).c_str());
263                 start++;
264         }
265
266         return ret + "]";
267 }
268
269 template <typename T>
270 synfig::String set_string(T set)
271 {
272         return set_string(set.begin(), set.end());
273 }
274 #endif // _DEBUG
275
276 typedef etl::handle<Node> NodeHandle;
277
278 }; // END of namespace synfig
279
280 /* === E N D =============================================================== */
281
282 #endif