00001
00022
00023
00024
00025
00026 #ifndef __SYNFIG_VALUENODE_H
00027 #define __SYNFIG_VALUENODE_H
00028
00029
00030
00031 #include "vector.h"
00032 #include "value.h"
00033 #include "string.h"
00034 #include "releases.h"
00035 #include <ETL/handle>
00036 #include <ETL/stringf>
00037 #include "exception.h"
00038 #include <map>
00039 #include <sigc++/signal.h>
00040 #include "guid.h"
00041
00042 #ifndef SYNFIG_NO_ANGLE
00043 #include <ETL/angle>
00044 #endif
00045
00046 #include "node.h"
00047
00048 #include <set>
00049
00050
00051
00052
00053
00054 #if ( __GNUC__ == 3 ) && ( __GNUC__MINOR__ == 0 )
00055 # define DCAST_HACK_BASECLASS() int cast__
00056 # define DCAST_HACK_ID(x) static const int my_cast__(void) { return x; }
00057 # define DCAST_HACK_ENABLE() cast__=my_cast__()
00058 #else
00059 # define DCAST_HACK_BASECLASS()
00060 # define DCAST_HACK_ID(x)
00061 # define DCAST_HACK_ENABLE()
00062 #endif
00063
00064 #define CHECK_TYPE_AND_SET_VALUE(variable, type) \
00065 \
00066 if (get_type() == ValueBase::TYPE_NIL) { \
00067 warning("%s:%d get_type() IS nil sometimes!", \
00068 __FILE__, __LINE__); \
00069 return false; \
00070 } \
00071 if (get_type() != ValueBase::TYPE_NIL && \
00072 !(ValueBase::same_type_as(value->get_type(), type)) && \
00073 !PlaceholderValueNode::Handle::cast_dynamic(value)) { \
00074 error(_("%s:%d wrong type for %s: need %s but got %s"), \
00075 __FILE__, __LINE__, \
00076 link_local_name(i).c_str(), \
00077 ValueBase::type_local_name(type).c_str(), \
00078 ValueBase::type_local_name(value->get_type()).c_str()); \
00079 return false; \
00080 } \
00081 variable = value; \
00082 signal_child_changed()(i); \
00083 signal_value_changed()(); \
00084 return true
00085
00086
00087
00088
00089
00090 namespace synfig {
00091
00092 class Canvas;
00093 class LinkableValueNode;
00094 class Layer;
00095
00099 class ValueNode : public synfig::Node
00100 {
00101 friend class Layer;
00102 friend class LinkableValueNode;
00103
00104
00105
00106
00107
00108 public:
00109
00110 typedef etl::handle<ValueNode> Handle;
00111
00112 typedef etl::loose_handle<ValueNode> LooseHandle;
00113
00114 typedef etl::handle<const ValueNode> ConstHandle;
00115
00116 typedef etl::rhandle<ValueNode> RHandle;
00117
00118
00119 static bool subsys_init();
00120
00121 static bool subsys_stop();
00122
00123
00124
00125
00126
00127 private:
00128 ValueBase::Type type;
00129 String name;
00130 etl::loose_handle<Canvas> canvas_;
00131 etl::loose_handle<Canvas> root_canvas_;
00132
00133
00134
00135
00136
00137 private:
00138
00140 sigc::signal<void> signal_value_changed_;
00141
00143 sigc::signal<void,int*> signal_children_reordered_;
00144
00146 sigc::signal<void,int> signal_child_changed_;
00147
00149 sigc::signal<void,int> signal_child_removed_;
00150
00152 sigc::signal<void,int> signal_child_inserted_;
00153
00155 sigc::signal<void> signal_id_changed_;
00156
00157
00158
00159
00160
00161 public:
00162
00164 sigc::signal<void>& signal_value_changed() { return signal_value_changed_; }
00165
00167 sigc::signal<void,int*>& signal_children_reordered() { return signal_children_reordered_; }
00168
00170 sigc::signal<void,int>& signal_child_changed() { return signal_child_changed_; }
00171
00173 sigc::signal<void,int>& signal_child_removed() { return signal_child_removed_; }
00174
00176 sigc::signal<void,int>& signal_child_inserted() { return signal_child_inserted_; }
00177
00179 sigc::signal<void>& signal_id_changed() { return signal_id_changed_; }
00180
00181
00182
00183
00184
00185 protected:
00186
00187 ValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
00188
00189 public:
00190
00191 virtual ~ValueNode();
00192
00193
00194
00195
00196
00197 public:
00198
00200 virtual ValueBase operator()(Time )const
00201 { return ValueBase(); }
00202
00204 void set_id(const String &x);
00205
00207
00209 const String &get_id()const { return name; }
00210
00212 virtual String get_name()const=0;
00213
00215 virtual String get_local_name()const=0;
00216
00218 virtual String get_description(bool show_exported_name = true)const;
00219
00220
00222 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const=0;
00223
00225 bool is_exported()const { return !get_id().empty(); }
00226
00228 ValueBase::Type get_type()const { return type; }
00229
00231 etl::loose_handle<Canvas> get_parent_canvas()const { return canvas_; }
00232
00234 etl::loose_handle<Canvas> get_root_canvas()const { return root_canvas_; }
00235
00237 void set_parent_canvas(etl::loose_handle<Canvas> x);
00238
00240 void set_root_canvas(etl::loose_handle<Canvas> x);
00241
00243 String get_relative_id(etl::loose_handle<const Canvas> x)const;
00244
00245 int replace(etl::handle<ValueNode> x);
00246
00247 protected:
00249 void set_type(ValueBase::Type t) { type=t; }
00250
00251 virtual void on_changed();
00252
00253 public:
00254 DCAST_HACK_BASECLASS();
00255 DCAST_HACK_ID(0);
00256 };
00257
00261 class PlaceholderValueNode : public ValueNode
00262 {
00263 public:
00264 typedef etl::handle<PlaceholderValueNode> Handle;
00265 typedef etl::loose_handle<PlaceholderValueNode> LooseHandle;
00266 typedef etl::handle<const PlaceholderValueNode> ConstHandle;
00267 typedef etl::rhandle<PlaceholderValueNode> RHandle;
00268
00269 private:
00270
00271 PlaceholderValueNode(ValueBase::Type type=ValueBase::TYPE_NIL);
00272
00273 public:
00274
00275 virtual ValueBase operator()(Time t)const;
00276
00277 virtual String get_name()const;
00278
00279 virtual String get_local_name()const;
00280
00281 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
00282
00283 static Handle create(ValueBase::Type type=ValueBase::TYPE_NIL);
00284
00285 protected:
00286 virtual void get_times_vfunc(Node::time_set &) const {}
00287 };
00288
00289
00293 class LinkableValueNode : public ValueNode
00294 {
00295 friend class ValueNode;
00296 public:
00297
00298 typedef etl::handle<LinkableValueNode> Handle;
00299
00300 typedef etl::loose_handle<LinkableValueNode> LooseHandle;
00301
00302 typedef etl::handle<const LinkableValueNode> ConstHandle;
00303
00304 typedef etl::rhandle<LinkableValueNode> RHandle;
00305
00306
00308 typedef LinkableValueNode* (*Factory)(const ValueBase&);
00309
00310 typedef bool (*CheckType)(ValueBase::Type);
00311
00312 struct BookEntry
00313 {
00314 String local_name;
00315 Factory factory;
00316 CheckType check_type;
00317 ReleaseVersion release_version;
00318 };
00319
00320 typedef std::map<String,BookEntry> Book;
00321
00322 static Book& book();
00323
00324 static Handle create(const String &name, const ValueBase& x);
00325
00326 static bool check_type(const String &name, ValueBase::Type x);
00327
00328 public:
00329 LinkableValueNode(ValueBase::Type type=ValueBase::TYPE_NIL):
00330 ValueNode(type) { }
00331
00332 protected:
00333 virtual bool set_link_vfunc(int i,ValueNode::Handle x)=0;
00334
00335 void unlink_all();
00336
00337 public:
00338
00339 virtual int link_count()const=0;
00340
00341 virtual String link_local_name(int i)const=0;
00342
00343 virtual String link_name(int i)const=0;
00344
00345 virtual int get_link_index_from_name(const String &name)const=0;
00346
00347 virtual ValueNode* clone(const GUID& deriv_guid=GUID())const;
00348
00349 bool set_link(int i,ValueNode::Handle x);
00350 bool set_link(const String &name,ValueNode::Handle x) { return set_link(get_link_index_from_name(name),x); }
00351
00352 ValueNode::LooseHandle get_link(int i)const;
00353 ValueNode::LooseHandle get_link(const String &name)const { return get_link(get_link_index_from_name(name)); }
00354
00355 String
00356 get_description(int index = -1, bool show_exported_name = true)const;
00357
00358 protected:
00360 void set_type(ValueBase::Type t) { ValueNode::set_type(t); }
00361
00362 virtual ValueNode::LooseHandle get_link_vfunc(int i)const=0;
00363
00364
00365 virtual LinkableValueNode* create_new()const=0;
00366
00367 virtual void get_times_vfunc(Node::time_set &set) const;
00368 };
00369
00375 class ValueNodeList : public std::list<ValueNode::RHandle>
00376 {
00377 int placeholder_count_;
00378 public:
00379 ValueNodeList();
00380
00382
00385 ValueNode::Handle find(const String &name);
00386
00388
00391 ValueNode::ConstHandle find(const String &name)const;
00392
00394 bool erase(ValueNode::Handle value_node);
00395
00397 bool add(ValueNode::Handle value_node);
00398
00400 bool count(const String &id)const;
00401
00403 ValueNode::Handle surefind(const String &name);
00404
00406 void audit();
00407
00409 int placeholder_count()const { return placeholder_count_; }
00410 };
00411
00412 ValueNode::LooseHandle find_value_node(const GUID& guid);
00413
00414 };
00415
00416
00417
00418 #endif