1 /* === S I N F G =========================================================== */
2 /*! \file value_node.cpp
3 ** \brief Template File
5 ** $Id: valuenode.cpp,v 1.1.1.1 2005/01/04 01:23:15 darco Exp $
8 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
10 ** This software and associated documentation
11 ** are CONFIDENTIAL and PROPRIETARY property of
12 ** the above-mentioned copyright holder.
14 ** You may not copy, print, publish, or in any
15 ** other way distribute this software without
16 ** a prior written agreement with
17 ** the copyright holder.
20 /* ========================================================================= */
22 /* === H E A D E R S ======================================================= */
24 #define SINFG_NO_ANGLE
26 //#define HAS_HASH_MAP 1
35 #include "valuenode.h"
39 #include "valuenode_const.h"
40 #include "valuenode_linear.h"
41 #include "valuenode_composite.h"
42 #include "valuenode_reference.h"
43 #include "valuenode_scale.h"
44 #include "valuenode_segcalctangent.h"
45 #include "valuenode_segcalcvertex.h"
46 #include "valuenode_stripes.h"
47 #include "valuenode_subtract.h"
48 #include "valuenode_timedswap.h"
49 #include "valuenode_twotone.h"
50 #include "valuenode_bline.h"
51 #include "valuenode_dynamiclist.h"
52 #include "valuenode_radialcomposite.h"
53 #include "valuenode_gradientrotate.h"
54 #include "valuenode_sine.h"
60 /* === U S I N G =========================================================== */
64 using namespace sinfg;
66 /* === M A C R O S ========================================================= */
68 /* === G L O B A L S ======================================================= */
70 static int value_node_count(0);
72 static LinkableValueNode::Book *book_;
75 ValueNode::LooseHandle
76 sinfg::find_value_node(const GUID& guid)
78 return guid_cast<ValueNode>(guid);
81 /* === P R O C E D U R E S ================================================= */
83 /* === M E T H O D S ======================================================= */
86 ValueNode::subsys_init()
88 book_=new LinkableValueNode::Book();
90 #define ADD_VALUENODE(c,n) (*book_)[n].factory=reinterpret_cast<LinkableValueNode::Factory>(&c::create); (*book_)[n].check_type=&c::check_type;(*book_)[n].local_name=n
91 #define ADD_VALUENODE2(c,n) (*book_)[n].factory=reinterpret_cast<LinkableValueNode::Factory>(&c::create_from); (*book_)[n].check_type=&c::check_type;(*book_)[n].local_name=n
93 ADD_VALUENODE(ValueNode_Linear,"linear");
94 ADD_VALUENODE(ValueNode_Composite,"composite");
95 ADD_VALUENODE(ValueNode_RadialComposite,"radial_composite");
96 ADD_VALUENODE(ValueNode_Reference,"reference");
97 ADD_VALUENODE(ValueNode_Scale,"scale");
98 ADD_VALUENODE(ValueNode_SegCalcTangent,"segcalctangent");
99 ADD_VALUENODE(ValueNode_SegCalcVertex,"segcalcvertex");
100 ADD_VALUENODE(ValueNode_Stripes,"stripes");
101 ADD_VALUENODE(ValueNode_Subtract,"subtract");
102 //ADD_VALUENODE(ValueNode_TimedSwap,"timed_swap");
103 ADD_VALUENODE(ValueNode_TwoTone,"twotone");
104 ADD_VALUENODE(ValueNode_BLine,"bline");
105 ADD_VALUENODE2(ValueNode_DynamicList,"dynamic_list");
106 ADD_VALUENODE(ValueNode_GradientRotate,"gradient_rotate");
107 ADD_VALUENODE(ValueNode_Sine,"sine");
114 ValueNode::subsys_stop()
117 /* if(global_value_node_map.size() || value_node_count)
120 sinfg::error("%d ValueNodes haven't been destroyed yet!",value_node_count);
122 if(global_value_node_map.size()!=value_node_count)
123 sinfg::error("value node count mismatch! map.size()!=value_node_count (%d!=%d)",global_value_node_map.size(),value_node_count);
125 GlobalValueNodeMap::iterator iter;
126 for(iter=global_value_node_map.begin();iter!=global_value_node_map.end();++iter)
128 if(!iter->second->is_exported())
129 sinfg::info("%s: count:%d name:%s type:%s",
130 iter->first.get_string().c_str(),
131 iter->second->count(),
132 iter->second->get_name().c_str(),
133 ValueBase::type_name(iter->second->get_type()).c_str()
136 sinfg::info("%s: id:%s count:%d name:%s type:%s",
137 iter->first.get_string().c_str(),
138 iter->second->get_id().c_str(),
139 iter->second->count(),
140 iter->second->get_name().c_str(),
141 ValueBase::type_name(iter->second->get_type()).c_str()
149 ValueNode::ValueNode(ValueBase::Type type):type(type)
154 LinkableValueNode::Book&
155 LinkableValueNode::book()
160 LinkableValueNode::Handle
161 LinkableValueNode::create(const String &name, const ValueBase& x)
163 if(!book().count(name))
165 return book()[name].factory(x);
169 LinkableValueNode::check_type(const String &name, ValueBase::Type x)
171 if(!book().count(name) || !book()[name].check_type)
173 return book()[name].check_type(x);
177 LinkableValueNode::set_link(int i,ValueNode::Handle x)
179 ValueNode::Handle previous(get_link(i));
181 if(set_link_vfunc(i,x))
184 remove_child(previous.get());
187 if(!x->is_exported() && get_parent_canvas())
189 x->set_parent_canvas(get_parent_canvas());
197 ValueNode::LooseHandle
198 LinkableValueNode::get_link(int i)const
200 return get_link_vfunc(i);
204 LinkableValueNode::unlink_all()
206 for(int i=0;i<link_count();i++)
208 ValueNode::LooseHandle value_node(get_link(i));
210 value_node->parent_set.erase(this);
214 ValueNode::~ValueNode()
224 ValueNode::on_changed()
226 if(get_parent_canvas())
227 get_parent_canvas()->signal_value_node_changed()(this);
228 else if(get_root_canvas() && get_parent_canvas())
229 get_root_canvas()->signal_value_node_changed()(this);
235 ValueNode::replace(etl::handle<ValueNode> x)
240 while(parent_set.size())
242 (*parent_set.begin())->add_child(x.get());
243 (*parent_set.begin())->remove_child(this);
244 //x->parent_set.insert(*parent_set.begin());
245 //parent_set.erase(parent_set.begin());
247 int r(RHandle(this).replace(x));
253 ValueNode::set_id(const String &x)
258 signal_id_changed_();
262 ValueNodeList::ValueNodeList():
263 placeholder_count_(0)
268 ValueNodeList::count(const String &id)const
275 for(iter=begin();iter!=end() && id!=(*iter)->get_id();++iter);
284 ValueNodeList::find(const String &id)
289 throw Exception::IDNotFound("Empty ID");
291 for(iter=begin();iter!=end() && id!=(*iter)->get_id();++iter);
294 throw Exception::IDNotFound("ValueNode in ValueNodeList: "+id);
299 ValueNode::ConstHandle
300 ValueNodeList::find(const String &id)const
305 throw Exception::IDNotFound("Empty ID");
307 for(iter=begin();iter!=end() && id!=(*iter)->get_id();++iter);
310 throw Exception::IDNotFound("ValueNode in ValueNodeList: "+id);
316 ValueNodeList::surefind(const String &id)
319 throw Exception::IDNotFound("Empty ID");
321 ValueNode::Handle value_node;
327 catch(Exception::IDNotFound)
329 value_node=PlaceholderValueNode::create();
330 value_node->set_id(id);
331 push_back(value_node);
332 placeholder_count_++;
339 ValueNodeList::erase(ValueNode::Handle value_node)
345 for(iter=begin();iter!=end();++iter)
346 if(value_node.get()==iter->get())
348 std::list<ValueNode::RHandle>::erase(iter);
349 if(PlaceholderValueNode::Handle::cast_dynamic(value_node))
350 placeholder_count_--;
357 ValueNodeList::add(ValueNode::Handle value_node)
361 if(value_node->get_id().empty())
366 ValueNode::RHandle other_value_node=find(value_node->get_id());
367 if(PlaceholderValueNode::Handle::cast_dynamic(other_value_node))
369 other_value_node->replace(value_node);
370 placeholder_count_--;
376 catch(Exception::IDNotFound)
378 push_back(value_node);
386 ValueNodeList::audit()
390 for(next=begin(),iter=next++;iter!=end();iter=next++)
392 std::list<ValueNode::RHandle>::erase(iter);
397 PlaceholderValueNode::get_name()const
399 return "placeholder";
403 PlaceholderValueNode::get_local_name()const
405 return _("Placeholder");
409 PlaceholderValueNode::clone(const GUID& deriv_guid)const
411 ValueNode* ret(new PlaceholderValueNode());
412 ret->set_guid(get_guid()^deriv_guid);
416 PlaceholderValueNode::Handle
417 PlaceholderValueNode::create(ValueBase::Type type)
419 return new PlaceholderValueNode(type);
423 PlaceholderValueNode::operator()(Time t)const
429 PlaceholderValueNode::PlaceholderValueNode(ValueBase::Type type):
435 LinkableValueNode::clone(const GUID& deriv_guid)const
437 { ValueNode* x(find_value_node(get_guid()^deriv_guid).get()); if(x)return x; }
440 LinkableValueNode *ret=create_new();
441 ret->set_guid(get_guid()^deriv_guid);
443 for(i=0;i<link_count();i++)
445 ValueNode::Handle link=get_link_vfunc(i);
446 if(!link->is_exported())
448 ValueNode::LooseHandle value_node(find_value_node(link->get_guid()^deriv_guid));
450 value_node=link->clone(deriv_guid);
451 ret->set_link(i,value_node);
454 ret->set_link(i,link);
461 ValueNode::get_relative_id(etl::loose_handle<const Canvas> x)const
463 assert(is_exported());
466 if(x.get()==canvas_.get())
469 return canvas_->_get_relative_id(x)+':'+get_id();
473 ValueNode::set_parent_canvas(etl::loose_handle<Canvas> x)
475 canvas_=x; if(x) root_canvas_=x->get_root();
479 ValueNode::set_root_canvas(etl::loose_handle<Canvas> x)
481 root_canvas_=x->get_root();
484 void LinkableValueNode::get_times_vfunc(Node::time_set &set) const
486 ValueNode::LooseHandle h;
488 int size = link_count();
490 //just add it to the set...
491 for(int i=0; i < size; ++i)
497 const Node::time_set &tset = h->get_times();
498 set.insert(tset.begin(),tset.end());