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