1 /* === S Y N F I G ========================================================= */
3 ** \brief Template File
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
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.
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.
22 /* ========================================================================= */
24 /* === H E A D E R S ======================================================= */
34 // #include "nodebase.h" // this defines a bunch of sigc::slots that are never used
44 /* === U S I N G =========================================================== */
48 using namespace synfig;
50 /* === M A C R O S ========================================================= */
52 // About BE_FRUGAL_WITH_GUIDS
53 // If this macro is set, then a GUID will NOT
54 // be calculated until the first call to get_guid()
55 // This also means that the node doesn't get
56 // added to the database until get_guid() is called
57 // for the first time, or set_guid() is called.
58 // If it is expensive to calculate GUIDs, then
59 // this can improve performance a tad in
60 // some cases. Otherwise, it doesn't change
62 #define BE_FRUGAL_WITH_GUIDS 1
67 # define __sys_clock ::clock
71 # define __sys_clock ::clock
74 extern clock_t _clock();
75 # define CLOCKS_PER_SEC 1000
76 # define __sys_clock _clock
81 /* === G L O B A L S ======================================================= */
84 typedef HASH_MAP_CLASS<synfig::GUID,Node*,GUIDHash> GlobalNodeMap;
86 typedef map<synfig::GUID,Node*> GlobalNodeMap;
89 //! A map to store all the GUIDs with a pointer to the Node.
90 static GlobalNodeMap* global_node_map_;
92 static GlobalNodeMap& global_node_map()
95 global_node_map_=new GlobalNodeMap;
96 return *global_node_map_;
99 /* === P R O C E D U R E S ================================================= */
102 synfig::find_node(const synfig::GUID& guid)
104 if(global_node_map().count(guid)==0)
106 return global_node_map()[guid];
110 refresh_node(synfig::Node* node, synfig::GUID old_guid)
112 assert(global_node_map().count(old_guid));
113 global_node_map().erase(old_guid);
114 assert(!global_node_map().count(old_guid));
115 global_node_map()[node->get_guid()]=node;
118 /* === M E T H O D S ======================================================= */
122 TimePoint::c_str()const
124 return get_time().get_string().c_str();
129 TimePoint::absorb(const TimePoint& x)
131 //! If the Time Point to absorb is itself then bail out
132 if(get_guid()==x.get_guid())
134 //! Creates a new GUID with the old and the new one using XOR operator
135 set_guid(get_guid()^x.get_guid());
136 //! If the current before/after interpolation is NIL use the interpolation
137 //! provided by the TimePoint to absorb
138 if(get_after()==INTERPOLATION_NIL)
139 set_after(x.get_after());
140 if(get_before()==INTERPOLATION_NIL)
141 set_before(x.get_before());
142 //! If the interpolation of the Time Point to absorb is not the same
143 //! than the interpolation from the Time Point to absorb then
144 //! use UNDEFINED interpolation
145 if(get_after()!=x.get_after() && x.get_after()!=INTERPOLATION_NIL)
146 set_after(INTERPOLATION_UNDEFINED);
147 if(get_before()!=x.get_before() && x.get_before()!=INTERPOLATION_NIL)
148 set_before(INTERPOLATION_UNDEFINED);
151 TimePointSet::iterator
152 TimePointSet::insert(const TimePoint& x)
154 //! finds a iterator to a Time Point with the same time
155 //! \see inline bool operator==(const TimePoint& lhs,const TimePoint& rhs)
156 iterator iter(find(x));
157 //! If iter is not a the end of the set (we found one Time Point)
160 //! Absorb the time point
161 const_cast<TimePoint&>(*iter).absorb(x);
164 //! Else, insert it at the first of the set
165 return std::set<TimePoint>::insert(x).first;
172 time_last_changed_(__sys_clock()),
175 #ifndef BE_FRUGAL_WITH_GUIDS
178 assert(!global_node_map().count(guid_));
179 global_node_map()[guid_]=this;
189 assert(global_node_map().count(guid_));
190 global_node_map().erase(guid_);
191 assert(!global_node_map().count(guid_));
198 time_last_changed_=__sys_clock();
203 //! Gets the GUID for this value node
205 Node::get_guid()const
207 #ifdef BE_FRUGAL_WITH_GUIDS
210 const_cast<synfig::GUID&>(guid_).make_unique();
212 assert(!global_node_map().count(guid_));
213 global_node_map()[guid_]=const_cast<Node*>(this);
220 //! Sets the GUID for this value node
222 Node::set_guid(const synfig::GUID& x)
226 #ifdef BE_FRUGAL_WITH_GUIDS
230 assert(!global_node_map().count(guid_));
231 global_node_map()[guid_]=this;
237 synfig::GUID oldguid(guid_);
239 refresh_node(this, oldguid);
240 on_guid_changed(oldguid);
245 Node::get_time_last_changed()const
247 return time_last_changed_;
251 Node::add_child(Node*x)
253 x->parent_set.insert(this);
257 Node::remove_child(Node*x)
259 if(x->parent_set.count(this)) x->parent_set.erase(this);
263 Node::parent_count()const
265 return parent_set.size();
268 const Node::time_set &
269 Node::get_times() const
274 get_times_vfunc(times);
278 //set the output set...
287 deleting_=true; signal_deleted()();
297 std::set<Node*>::iterator iter;
298 for(iter=parent_set.begin();iter!=parent_set.end();++iter)
305 Node::on_guid_changed(synfig::GUID guid)
307 signal_guid_changed()(guid);