|
From: <br...@us...> - 2008-09-26 04:14:15
|
Revision: 3693
http://openvrml.svn.sourceforge.net/openvrml/?rev=3693&view=rev
Author: braden
Date: 2008-09-26 04:14:04 +0000 (Fri, 26 Sep 2008)
Log Message:
-----------
Moved PROTO implementation classes to the openvrml::local namespace and out of browser.cpp.
Modified Paths:
--------------
trunk/ChangeLog
trunk/src/Makefile.am
trunk/src/libopenvrml/openvrml/browser.cpp
trunk/src/libopenvrml/openvrml/node.h
Added Paths:
-----------
trunk/src/libopenvrml/openvrml/local/proto.cpp
trunk/src/libopenvrml/openvrml/local/proto.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2008-09-25 02:08:05 UTC (rev 3692)
+++ trunk/ChangeLog 2008-09-26 04:14:04 UTC (rev 3693)
@@ -1,3 +1,16 @@
+2008-09-26 Braden McDaniel <br...@en...>
+
+ Moved PROTO implementation classes to the openvrml::local
+ namespace and out of browser.cpp.
+
+ * src/Makefile.am
+ (libopenvrml_libopenvrml_la_SOURCES): Added
+ libopenvrml/openvrml/local/proto.{cpp,h}.
+ * src/libopenvrml/openvrml/browser.cpp
+ * src/libopenvrml/openvrml/local/proto.cpp
+ * src/libopenvrml/openvrml/local/proto.h
+ * src/libopenvrml/openvrml/node.h
+
2008-09-24 Braden McDaniel <br...@en...>
Moved dlopen/LoadLibrary wrapper functions, the XML parser
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2008-09-25 02:08:05 UTC (rev 3692)
+++ trunk/src/Makefile.am 2008-09-26 04:14:04 UTC (rev 3693)
@@ -155,7 +155,9 @@
libopenvrml/openvrml/local/uri.cpp \
libopenvrml/openvrml/local/uri.h \
libopenvrml/openvrml/local/xml_reader.cpp \
- libopenvrml/openvrml/local/xml_reader.h
+ libopenvrml/openvrml/local/xml_reader.h \
+ libopenvrml/openvrml/local/proto.cpp \
+ libopenvrml/openvrml/local/proto.h
libopenvrml_libopenvrml_la_LDFLAGS = \
-version-info $(LIBOPENVRML_LIBRARY_VERSION) \
Modified: trunk/src/libopenvrml/openvrml/browser.cpp
===================================================================
--- trunk/src/libopenvrml/openvrml/browser.cpp 2008-09-25 02:08:05 UTC (rev 3692)
+++ trunk/src/libopenvrml/openvrml/browser.cpp 2008-09-26 04:14:04 UTC (rev 3693)
@@ -42,6 +42,7 @@
# include "x3d_cad_geometry.h"
# include <openvrml/local/uri.h>
# include <openvrml/local/xml_reader.h>
+# include <openvrml/local/proto.h>
# include <private.h>
# include <boost/algorithm/string/predicate.hpp>
# include <boost/bind.hpp>
@@ -107,2221 +108,6 @@
const initial_value_map & initial_values) const
OPENVRML_NOTHROW;
};
-
-
- class proto_node;
- class proto_node_type;
- class proto_impl_cloner;
-
- /**
- * @internal
- *
- * @brief @c node_metatype for @c PROTO%s.
- *
- * The @c proto_node_metatype is OpenVRML's in-memory representation of a
- * @c PROTO (as opposed to a @c PROTO instance). Through the
- * @c proto_node_type intermediary, it facilitates spawning any number of
- * @c proto_node instances.
- */
- class OPENVRML_LOCAL proto_node_metatype : public node_metatype {
- friend class proto_node;
- friend class proto_node_type;
- friend class proto_impl_cloner;
-
- public:
- class is_target {
- public:
- node * impl_node;
- std::string impl_node_interface;
-
- is_target(node & impl_node,
- const std::string & impl_node_interface);
- };
-
- typedef std::multimap<std::string, is_target> is_map_t;
-
- class route {
- public:
- node * from;
- std::string eventout;
- node * to;
- std::string eventin;
-
- route(node & from, const std::string & eventout,
- node & to, const std::string & eventin);
- };
-
- typedef std::vector<route> routes_t;
-
- typedef std::map<std::string, boost::shared_ptr<field_value> >
- default_value_map_t;
-
- private:
- node_interface_set interfaces;
- default_value_map_t default_value_map;
- std::vector<boost::intrusive_ptr<node> > impl_nodes;
- routes_t routes;
- is_map_t is_map;
-
- public:
- proto_node_metatype(
- const node_metatype_id & id,
- openvrml::browser & browser,
- const node_interface_set & interfaces,
- const default_value_map_t & default_value_map,
- const std::vector<boost::intrusive_ptr<node> > & impl_nodes,
- const is_map_t & is_map,
- const routes_t & routes);
- virtual ~proto_node_metatype() OPENVRML_NOTHROW;
-
- virtual const boost::shared_ptr<node_type>
- do_create_type(const std::string & id,
- const node_interface_set & interfaces) const
- OPENVRML_THROW2(unsupported_interface, std::bad_alloc);
- };
-
-
- /**
- * @internal
- *
- * @brief @c node_type for @c PROTO node instances.
- */
- class OPENVRML_LOCAL proto_node_type : public node_type {
- node_interface_set interfaces_;
-
- public:
- proto_node_type(const proto_node_metatype & node_metatype,
- const std::string & id,
- const node_interface_set & interfaces)
- OPENVRML_THROW2(unsupported_interface, std::bad_alloc);
- virtual ~proto_node_type() OPENVRML_NOTHROW;
-
- private:
- virtual const node_interface_set & do_interfaces() const
- OPENVRML_NOTHROW;
- virtual const boost::intrusive_ptr<node>
- do_create_node(const boost::shared_ptr<openvrml::scope> & scope,
- const initial_value_map & initial_values) const
- OPENVRML_THROW1(std::bad_alloc);
- };
-
-
- class OPENVRML_LOCAL abstract_proto_node : public openvrml::node {
- public:
- virtual ~abstract_proto_node() OPENVRML_NOTHROW = 0;
-
- protected:
- template <typename FieldValue>
- class proto_eventin : public node_field_value_listener<FieldValue> {
- typedef std::set<field_value_listener<FieldValue> *> listeners;
- listeners listeners_;
-
- public:
- typedef FieldValue field_value_type;
- typedef field_value_listener<FieldValue> event_listener_type;
-
- explicit proto_eventin(abstract_proto_node & node);
- virtual ~proto_eventin() OPENVRML_NOTHROW;
-
- bool is(event_listener_type & listener)
- OPENVRML_THROW1(std::bad_alloc);
-
- protected:
- virtual void do_process_event(const FieldValue & value,
- double timestamp)
- OPENVRML_THROW1(std::bad_alloc);
-
- private:
- virtual const std::string do_eventin_id() const OPENVRML_NOTHROW;
- };
-
- struct proto_eventin_creator {
- proto_eventin_creator(
- const openvrml::field_value::type_id type,
- abstract_proto_node & node,
- boost::shared_ptr<openvrml::event_listener> & listener):
- type_(type),
- node_(&node),
- listener_(&listener)
- {}
-
- template <typename T>
- void operator()(T) const
- {
- if (T::field_value_type_id == this->type_) {
- this->listener_->reset(new proto_eventin<T>(*this->node_));
- }
- }
-
- private:
- openvrml::field_value::type_id type_;
- abstract_proto_node * node_;
- boost::shared_ptr<openvrml::event_listener> * listener_;
- };
-
- static boost::shared_ptr<openvrml::event_listener>
- create_eventin(field_value::type_id, abstract_proto_node & node)
- OPENVRML_THROW1(std::bad_alloc);
-
- struct eventin_is {
- eventin_is(const field_value::type_id field_type,
- openvrml::event_listener & impl_eventin,
- openvrml::event_listener & interface_eventin):
- type_(field_type),
- impl_eventin_(&impl_eventin),
- interface_eventin_(&interface_eventin)
- {}
-
- template <typename T>
- void operator()(T) const
- {
- if (T::field_value_type_id == this->type_) {
- dynamic_cast<proto_eventin<T> &>(*interface_eventin_).is(
- dynamic_cast<field_value_listener<T> &>(
- *impl_eventin_));
- }
- }
-
- private:
- field_value::type_id type_;
- openvrml::event_listener * impl_eventin_;
- openvrml::event_listener * interface_eventin_;
- };
-
- template <typename FieldValue>
- class proto_eventout : public field_value_emitter<FieldValue> {
- protected:
- class listener_t : public node_field_value_listener<FieldValue> {
- proto_eventout & emitter;
-
- public:
- abstract_proto_node & node;
- FieldValue value;
-
- listener_t(proto_eventout & emitter,
- abstract_proto_node & node,
- const FieldValue & initial_value);
- virtual ~listener_t() OPENVRML_NOTHROW;
-
- private:
- virtual const std::string do_eventin_id() const
- OPENVRML_NOTHROW;
- virtual void do_process_event(const FieldValue & value,
- double timestamp)
- OPENVRML_THROW1(std::bad_alloc);
- } listener;
-
- public:
- typedef FieldValue field_value_type;
- typedef field_value_emitter<FieldValue> event_emitter_type;
- typedef field_value_listener<FieldValue> event_listener_type;
-
- proto_eventout(
- abstract_proto_node & node,
- const FieldValue & initial_value = FieldValue());
- virtual ~proto_eventout() OPENVRML_NOTHROW;
-
- bool is(event_emitter_type & emitter)
- OPENVRML_THROW1(std::bad_alloc);
-
- private:
- const std::string do_eventout_id() const OPENVRML_NOTHROW;
- };
-
- struct proto_eventout_creator {
- proto_eventout_creator(
- const openvrml::field_value::type_id type,
- abstract_proto_node & node,
- boost::shared_ptr<openvrml::event_emitter> & emitter):
- type_(type),
- node_(&node),
- emitter_(&emitter)
- {}
-
- template <typename T>
- void operator()(T) const
- {
- if (T::field_value_type_id == this->type_) {
- this->emitter_->reset(new proto_eventout<T>(*this->node_));
- }
- }
-
- private:
- openvrml::field_value::type_id type_;
- abstract_proto_node * node_;
- boost::shared_ptr<openvrml::event_emitter> * emitter_;
- };
-
- static boost::shared_ptr<openvrml::event_emitter>
- create_eventout(field_value::type_id, abstract_proto_node & node)
- OPENVRML_THROW1(std::bad_alloc);
-
- struct eventout_is {
- eventout_is(const field_value::type_id field_type,
- openvrml::event_emitter & impl_eventout,
- openvrml::event_emitter & interface_eventout):
- type_(field_type),
- impl_eventout_(&impl_eventout),
- interface_eventout_(&interface_eventout)
- {}
-
- template <typename T>
- void operator()(T) const
- {
- if (T::field_value_type_id == this->type_) {
- dynamic_cast<proto_eventout<T> &>(*interface_eventout_).is(
- dynamic_cast<field_value_emitter<T> &>(
- *impl_eventout_));
- }
- }
-
- private:
- field_value::type_id type_;
- openvrml::event_emitter * impl_eventout_;
- openvrml::event_emitter * interface_eventout_;
- };
-
- typedef boost::shared_ptr<openvrml::event_listener> eventin_ptr;
- typedef std::map<std::string, eventin_ptr> eventin_map_t;
-
- struct proto_eventin_equal_to :
- std::unary_function<eventin_map_t::value_type, bool> {
-
- explicit proto_eventin_equal_to(
- const openvrml::event_listener & listener):
- listener_(&listener)
- {}
-
- bool operator()(const eventin_map_t::value_type & arg) const
- {
- return this->listener_ == arg.second.get();
- }
-
- private:
- const openvrml::event_listener * listener_;
- };
-
- eventin_map_t eventin_map;
-
- typedef boost::shared_ptr<openvrml::event_emitter> eventout_ptr;
- typedef std::map<std::string, eventout_ptr> eventout_map_t;
-
- struct proto_eventout_equal_to :
- std::unary_function<eventout_map_t::value_type, bool> {
-
- explicit proto_eventout_equal_to(
- const openvrml::event_emitter & emitter):
- emitter_(&emitter)
- {}
-
- bool operator()(const eventout_map_t::value_type & arg) const
- {
- return this->emitter_ == arg.second.get();
- }
-
- private:
- const openvrml::event_emitter * emitter_;
- };
-
- eventout_map_t eventout_map;
-
- abstract_proto_node(const openvrml::node_type & type,
- const boost::shared_ptr<openvrml::scope> & scope)
- OPENVRML_NOTHROW;
- };
-
- abstract_proto_node::abstract_proto_node(
- const openvrml::node_type & type,
- const boost::shared_ptr<openvrml::scope> & scope)
- OPENVRML_NOTHROW:
- openvrml::node(type, scope)
- {}
-
- abstract_proto_node::~abstract_proto_node() OPENVRML_NOTHROW
- {}
-
-
- /**
- * @internal
- *
- * @brief A @c PROTO instance node.
- *
- * Like a typical node implementation, @c proto_node%s have a many-to-one
- * relationship with the @c proto_node_type instance that creates them.
- * And @c proto_node_type has, in turn, a many-to-one relationship with
- * the @c proto_node_metatype instance that creates them. Unlike a
- * typical node implementation, there will very likely be more than one
- * @c proto_node_metatype instance known to the @c browser instance; there
- * will be one for each @c PROTO known to the @c browser.
- *
- * As the @c proto_node_metatype encodes the data in a @c PROTO, the
- * @c proto_node_type can be seen as modeling @c EXTERNPROTO. Each
- * @c EXTERNPROTO will spawn a new @c proto_node_type from the
- * @c proto_node_metatype that corresponds to the @c PROTO to which the
- * @c EXTERNPROTO refers. Recall that an @c EXTERNPROTO provides a subset
- * of the interfaces defined for a @c PROTO; thus, for a @c PROTO with
- * <var>n</var> interfaces, there are <var>n</var>! possible unique
- * @c EXTERNPROTO%s (and thus unique @c proto_node_type instances).
- *
- * Structurally, the implementation of @c proto_node is very similar to
- * that of @c proto_node_metatype. The difference is that event pathways
- * for @c ROUTE%s and @c IS mappings are actually created in the
- * @c proto_node. The @c proto_node_metatype, on the other hand, includes
- * metadata about how these event pathways @e should be created.
- */
- class OPENVRML_LOCAL proto_node : public abstract_proto_node {
- friend class externproto_node;
-
- template <typename FieldValue>
- class proto_exposedfield : public proto_eventin<FieldValue>,
- public proto_eventout<FieldValue> {
- public:
- proto_exposedfield(abstract_proto_node & node,
- const FieldValue & initial_value);
- virtual ~proto_exposedfield() OPENVRML_NOTHROW;
-
- private:
- virtual void do_process_event(const FieldValue & value,
- double timestamp)
- OPENVRML_THROW1(std::bad_alloc);
- };
-
- struct proto_exposedfield_creator {
- proto_exposedfield_creator(
- const field_value & initial_value,
- proto_node & node,
- boost::shared_ptr<openvrml::event_listener> & exposedfield):
- initial_value_(&initial_value),
- node_(&node),
- exposedfield_(&exposedfield)
- {}
-
- template <typename T>
- void operator()(T) const
- {
- if (T::field_value_type_id == this->initial_value_->type()) {
- using boost::polymorphic_downcast;
- this->exposedfield_->reset(
- new proto_exposedfield<T>(
- *this->node_,
- *polymorphic_downcast<const T *>(
- this->initial_value_)));
- }
- }
-
- private:
- const openvrml::field_value * initial_value_;
- proto_node * node_;
- boost::shared_ptr<openvrml::event_listener> * exposedfield_;
- };
-
- static boost::shared_ptr<openvrml::event_listener>
- create_exposedfield(const field_value & initial_value,
- proto_node & node)
- OPENVRML_THROW1(std::bad_alloc);
-
- boost::shared_ptr<openvrml::scope> proto_scope;
- std::vector<boost::intrusive_ptr<node> > impl_nodes;
-
- public:
- proto_node(const node_type & type,
- const boost::shared_ptr<openvrml::scope> & scope,
- const initial_value_map & initial_values)
- OPENVRML_THROW1(std::bad_alloc);
- virtual ~proto_node() OPENVRML_NOTHROW;
-
- virtual bool modified() const;
-
- private:
- virtual void do_initialize(double timestamp)
- OPENVRML_THROW1(std::bad_alloc);
-
- virtual const field_value & do_field(const std::string & id) const
- OPENVRML_THROW1(unsupported_interface);
- virtual openvrml::event_listener &
- do_event_listener(const std::string & id)
- OPENVRML_THROW1(unsupported_interface);
- virtual openvrml::event_emitter &
- do_event_emitter(const std::string & id)
- OPENVRML_THROW1(unsupported_interface);
-
- virtual void do_shutdown(double timestamp) OPENVRML_NOTHROW;
-
- virtual script_node * to_script() OPENVRML_NOTHROW;
- virtual appearance_node * to_appearance() OPENVRML_NOTHROW;
- virtual bounded_volume_node * to_bounded_volume() OPENVRML_NOTHROW;
- virtual child_node * to_child() OPENVRML_NOTHROW;
- virtual color_node * to_color() OPENVRML_NOTHROW;
- virtual color_rgba_node * to_color_rgba() OPENVRML_NOTHROW;
- virtual coordinate_node * to_coordinate() OPENVRML_NOTHROW;
- virtual font_style_node * to_font_style() OPENVRML_NOTHROW ;
- virtual geometry_node * to_geometry() OPENVRML_NOTHROW;
- virtual grouping_node * to_grouping() OPENVRML_NOTHROW;
- virtual light_node * to_light() OPENVRML_NOTHROW;
- virtual material_node * to_material() OPENVRML_NOTHROW;
- virtual navigation_info_node * to_navigation_info() OPENVRML_NOTHROW;
- virtual normal_node * to_normal() OPENVRML_NOTHROW;
- virtual pointing_device_sensor_node * to_pointing_device_sensor()
- OPENVRML_NOTHROW;
- virtual scoped_light_node * to_scoped_light() OPENVRML_NOTHROW;
- virtual sound_source_node * to_sound_source() OPENVRML_NOTHROW;
- virtual texture_node * to_texture() OPENVRML_NOTHROW;
- virtual texture_coordinate_node * to_texture_coordinate()
- OPENVRML_NOTHROW;
- virtual texture_transform_node * to_texture_transform()
- OPENVRML_NOTHROW;
- virtual time_dependent_node * to_time_dependent() OPENVRML_NOTHROW;
- virtual transform_node * to_transform() OPENVRML_NOTHROW;
- virtual viewpoint_node * to_viewpoint() OPENVRML_NOTHROW;
- };
-
-
- class OPENVRML_LOCAL node_path_element {
- public:
- std::vector<boost::intrusive_ptr<node> >::size_type index;
- field_value::type_id field_type;
- std::string field_id;
-
- node_path_element();
- };
-
- node_path_element::node_path_element():
- index(0),
- field_type(field_value::invalid_type_id)
- {}
-
- /**
- * @brief A @c node path is used to store the path to a @c node for the
- * purpose of duplicating a route in a cloned @c node hierarchy.
- */
- typedef std::list<node_path_element> node_path_t;
-
- class OPENVRML_LOCAL path_getter : boost::noncopyable {
- const node & objective;
- node_path_t & node_path;
- bool found;
-
- public:
- path_getter(const node & objective, node_path_t & node_path)
- OPENVRML_NOTHROW;
-
- void get_path_from(const boost::intrusive_ptr<node> & node)
- OPENVRML_THROW1(std::bad_alloc);
- void get_path_from(
- const std::vector<boost::intrusive_ptr<node> > & nodes)
- OPENVRML_THROW1(std::bad_alloc);
-
- private:
- void traverse_children(node & n) OPENVRML_THROW1(std::bad_alloc);
- };
-
- path_getter::path_getter(const node & objective, node_path_t & node_path)
- OPENVRML_NOTHROW:
- objective(objective),
- node_path(node_path),
- found(false)
- {}
-
- void path_getter::get_path_from(const boost::intrusive_ptr<node> & node)
- OPENVRML_THROW1(std::bad_alloc)
- {
- if (node) {
- this->node_path.push_back(node_path_element());
- if (node.get() == &objective) {
- this->found = true;
- return;
- }
- this->traverse_children(*node);
- if (!this->found) { this->node_path.pop_back(); }
- }
- }
-
- void path_getter::get_path_from(
- const std::vector<boost::intrusive_ptr<node> > & nodes)
- OPENVRML_THROW1(std::bad_alloc)
- {
- this->node_path.push_back(node_path_element());
- node_path_element & back = this->node_path.back();
- while (back.index < nodes.size()) {
- assert(&back == &this->node_path.back());
- if (nodes[back.index].get() == &this->objective) {
- this->found = true;
- return;
- }
- if (nodes[back.index].get()) {
- this->traverse_children(*nodes[back.index]);
- }
- //
- // We need to bail early to avoid incrementing the counter.
- //
- if (this->found) { return; }
- ++back.index;
- }
- if (!this->found) { this->node_path.pop_back(); }
- }
-
- void path_getter::traverse_children(node & n)
- OPENVRML_THROW1(std::bad_alloc)
- {
- const node_interface_set & interfaces = n.type().interfaces();
- node_path_element & back = this->node_path.back();
- for (node_interface_set::const_iterator interface_ = interfaces.begin();
- !this->found && interface_ != interfaces.end();
- ++interface_) {
- assert(&back == &this->node_path.back());
- if (interface_->type == node_interface::field_id
- || interface_->type == node_interface::exposedfield_id) {
- if (interface_->field_type == field_value::sfnode_id) {
- back.field_type = field_value::sfnode_id;
- back.field_id = interface_->id;
- try {
- const sfnode value = n.field<sfnode>(interface_->id);
- this->get_path_from(value.value());
- } catch (unsupported_interface & ex) {
- OPENVRML_PRINT_EXCEPTION_(ex);
- }
- } else if (interface_->field_type == field_value::mfnode_id) {
- back.field_type = field_value::mfnode_id;
- back.field_id = interface_->id;
- try {
- const mfnode value = n.field<mfnode>(interface_->id);
- this->get_path_from(value.value());
- } catch (unsupported_interface & ex) {
- OPENVRML_PRINT_EXCEPTION_(ex);
- }
- }
- }
- }
- }
-
- /**
- * @internal
- *
- * @brief Get the path to a node.
- *
- * @return the path to a node.
- */
- OPENVRML_LOCAL const node_path_t
- get_path(const std::vector<boost::intrusive_ptr<node> > & root,
- const node & objective)
- OPENVRML_THROW1(std::bad_alloc)
- {
- node_path_t path;
- path_getter(objective, path).get_path_from(root);
- return path;
- }
-
- /**
- * @internal
- *
- * @brief Resolve a node path against a node hierarchy.
- *
- * @return a pointer to the objective node in the node hierarchy
- * designated by @p root.
- */
- OPENVRML_LOCAL node *
- resolve_node_path(const node_path_t & path,
- const std::vector<boost::intrusive_ptr<node> > & root)
- {
- using boost::next;
- using boost::prior;
- assert(!path.empty());
- node * result = root[path.front().index].get();
- const node_path_t::const_iterator before_end = prior(path.end());
- for (node_path_t::const_iterator path_element = path.begin();
- path_element != before_end;
- ++path_element) {
- assert(result);
- try {
- if (path_element->field_type == field_value::sfnode_id) {
- result = result->field<sfnode>(path_element->field_id)
- .value().get();
- } else if (path_element->field_type == field_value::mfnode_id)
- {
- result = result->field<mfnode>(path_element->field_id)
- .value()[next(path_element)->index].get();
- } else {
- assert(!"invalid path_element->field_type");
- }
- } catch (unsupported_interface & ex) {
- OPENVRML_PRINT_EXCEPTION_(ex);
- }
- }
- return result;
- }
-
- class OPENVRML_LOCAL field_value_cloner {
- protected:
- const boost::shared_ptr<openvrml::scope> & target_scope;
- std::set<node *> traversed_nodes;
-
- public:
- explicit field_value_cloner(
- const boost::shared_ptr<openvrml::scope> & target_scope):
- target_scope(target_scope)
- {
- assert(target_scope);
- }
-
- virtual ~field_value_cloner()
- {}
-
- void clone_field_value(const boost::intrusive_ptr<node> & src_node,
- const field_value & src,
- field_value & dest)
- OPENVRML_THROW1(std::bad_alloc)
- {
- assert(src.type() == dest.type());
- const field_value::type_id type = src.type();
- if (type == field_value::sfnode_id) {
- this->clone_sfnode(src_node,
- static_cast<const sfnode &>(src),
- static_cast<sfnode &>(dest));
- } else if (type == field_value::mfnode_id) {
- this->clone_mfnode(src_node,
- static_cast<const mfnode &>(src),
- static_cast<mfnode &>(dest));
- } else {
- //
- // Do a shallow copy for other types.
- //
- dest.assign(src);
- }
- }
-
- private:
- virtual const boost::intrusive_ptr<node>
- clone_node(const boost::intrusive_ptr<node> & n)
- OPENVRML_THROW1(std::bad_alloc)
- {
- using std::set;
- using boost::intrusive_ptr;
-
- assert(this->target_scope);
-
- intrusive_ptr<node> result;
-
- if (!n) { return result; }
-
- const bool already_traversed =
- (this->traversed_nodes.find(n.get())
- != this->traversed_nodes.end());
-
- if (already_traversed) {
- result = intrusive_ptr<node>(
- this->target_scope->find_node(n->id()));
- assert(result);
- } else {
- initial_value_map initial_values;
- const node_interface_set & interfaces =
- n->type().interfaces();
- for (node_interface_set::const_iterator interface_ =
- interfaces.begin();
- interface_ != interfaces.end();
- ++interface_) {
- using std::string;
- const node_interface::type_id type = interface_->type;
- const string & id = interface_->id;
- if (type == node_interface::exposedfield_id
- || type == node_interface::field_id) {
- using std::auto_ptr;
- using boost::shared_ptr;
- auto_ptr<field_value> src = n->field(id);
- auto_ptr<field_value> dest =
- field_value::create(interface_->field_type);
- assert(src->type() == dest->type());
- this->clone_field_value(n, *src, *dest);
- bool succeeded =
- initial_values.insert(
- make_pair(id, shared_ptr<field_value>(dest)))
- .second;
- assert(succeeded);
- }
- }
- result = n->type().create_node(this->target_scope,
- initial_values);
- if (!n->id().empty()) { result->id(n->id()); }
- }
- return result;
- }
-
- void clone_sfnode(const boost::intrusive_ptr<node> & src_node,
- const sfnode & src,
- sfnode & dest)
- OPENVRML_THROW1(std::bad_alloc)
- {
- dest.value((src.value() == src_node)
- ? node::self_tag
- : this->clone_node(src.value()));
- }
-
- void clone_mfnode(const boost::intrusive_ptr<node> & src_node,
- const mfnode & src,
- mfnode & dest)
- OPENVRML_THROW1(std::bad_alloc)
- {
- using std::swap;
- using std::vector;
- std::vector<boost::intrusive_ptr<node> > result(
- src.value().size());
- for (vector<boost::intrusive_ptr<node> >::size_type i = 0;
- i < src.value().size();
- ++i) {
- result[i] = (src.value()[i] == src_node)
- ? node::self_tag
- : this->clone_node(src.value()[i]);
- }
- dest.value(result);
- }
- };
-
- //
- // Clone the implementation nodes.
- //
- class OPENVRML_LOCAL proto_impl_cloner : public field_value_cloner {
- const proto_node_metatype & node_metatype;
- const initial_value_map & initial_values_;
-
- public:
- proto_impl_cloner(
- const proto_node_metatype & node_metatype,
- const initial_value_map & initial_values,
- const boost::shared_ptr<openvrml::scope> & target_scope):
- field_value_cloner(target_scope),
- node_metatype(node_metatype),
- initial_values_(initial_values)
- {}
-
- const std::vector<boost::intrusive_ptr<node> > clone()
- OPENVRML_THROW1(std::bad_alloc)
- {
- using std::vector;
-
- vector<boost::intrusive_ptr<node> > result(
- this->node_metatype.impl_nodes.size());
-
- for (vector<boost::intrusive_ptr<node> >::size_type i = 0;
- i < this->node_metatype.impl_nodes.size();
- ++i) {
- result[i] = this->clone_node(this->node_metatype.impl_nodes[i]);
- assert(result[i]);
- }
- return result;
- }
-
- private:
- struct matches_is_target :
- std::unary_function<proto_node_metatype::is_map_t::value_type,
- bool> {
-
- explicit matches_is_target(
- const proto_node_metatype::is_target & is_target):
- is_target(is_target)
- {}
-
- result_type operator()(const argument_type & is_map_value) const
- {
- return (is_map_value.second.impl_node
- == this->is_target.impl_node)
- && (is_map_value.second.impl_node_interface
- == this->is_target.impl_node_interface);
- }
-
- private:
- const proto_node_metatype::is_target & is_target;
- };
-
- virtual const boost::intrusive_ptr<node>
- clone_node(const boost::intrusive_ptr<node> & n)
- OPENVRML_THROW1(std::bad_alloc)
- {
- using std::set;
- using boost::intrusive_ptr;
-
- assert(this->target_scope);
-
- intrusive_ptr<node> result;
-
- if (!n) { return result; }
-
- const bool already_traversed =
- (this->traversed_nodes.find(n.get())
- != this->traversed_nodes.end());
-
- if (already_traversed) {
- result = intrusive_ptr<node>(
- this->target_scope->find_node(n->id()));
- assert(result);
- } else {
- initial_value_map initial_values;
- const node_interface_set & interfaces =
- n->type().interfaces();
- for (node_interface_set::const_iterator interface_ =
- interfaces.begin();
- interface_ != interfaces.end();
- ++interface_) {
- using std::string;
- const node_interface::type_id type = interface_->type;
- const string & id = interface_->id;
- if (type == node_interface::exposedfield_id
- || type == node_interface::field_id) {
- using std::auto_ptr;
- using std::find_if;
- using boost::shared_ptr;
- auto_ptr<const field_value> src_val;
- auto_ptr<field_value> dest_val;
-
- //
- // If the field/exposedField is IS'd, get the value
- // from the initial_values_, or alternatively the
- // default_values_.
- //
- typedef proto_node_metatype::is_target is_target;
- typedef proto_node_metatype::is_map_t is_map;
- typedef proto_node_metatype::default_value_map_t
- default_value_map;
-
- is_map::const_iterator is_mapping =
- find_if(this->node_metatype.is_map.begin(),
- this->node_metatype.is_map.end(),
- matches_is_target(
- is_target(*n, interface_->id)));
- if (is_mapping != this->node_metatype.is_map.end()) {
- using boost::bind;
- using std::logical_or;
- //
- // If an exposedField in the implementation is IS'd
- // to an eventIn or an eventOut in the interface,
- // we'll still get here. So if the implementation
- // node interface is an exposedField, we need to
- // check to see if the PROTO interface is an
- // eventIn or an eventOut.
- //
- node_interface_set::const_iterator
- proto_interface =
- find_if(this->node_metatype.interfaces.begin(),
- this->node_metatype.interfaces.end(),
- bind(logical_or<bool>(),
- bind(node_interface_matches_exposedfield(),
- _1,
- is_mapping->first),
- bind(node_interface_matches_field(),
- _1,
- is_mapping->first)));
-
- if (proto_interface
- != this->node_metatype.interfaces.end()) {
- initial_value_map::const_iterator
- initial_value =
- this->initial_values_.find(
- is_mapping->first);
- if (initial_value
- != this->initial_values_.end()) {
- dest_val = initial_value->second->clone();
- } else {
- default_value_map::const_iterator
- default_value =
- this->node_metatype.default_value_map
- .find(is_mapping->first);
- assert(default_value
- != this->node_metatype
- .default_value_map.end());
- src_val = default_value->second->clone();
- }
- } else {
- src_val = n->field(id);
- }
- } else {
- src_val = n->field(id);
- }
-
- //
- // See above logic; we don't clone subtrees from the
- // initial_values; just ones from the default values
- // and the PROTO definition body.
- //
- if (src_val.get()) {
- assert(!dest_val.get());
- dest_val =
- field_value::create(interface_->field_type);
- this->clone_field_value(n, *src_val, *dest_val);
- }
-
- assert(dest_val.get());
-
- bool succeeded =
- initial_values.insert(
- make_pair(id,
- shared_ptr<field_value>(dest_val)))
- .second;
- assert(succeeded);
- }
- }
- result = n->type().create_node(this->target_scope,
- initial_values);
- if (!n->id().empty()) { result->id(n->id()); }
- }
- return result;
- }
-
- void clone_sfnode(const sfnode & src, sfnode & dest)
- OPENVRML_THROW1(std::bad_alloc)
- {
- dest.value(this->clone_node(src.value()));
- }
-
- void clone_mfnode(const mfnode & src, mfnode & dest)
- OPENVRML_THROW1(std::bad_alloc)
- {
- using std::swap;
- using std::vector;
- vector<boost::intrusive_ptr<node> > result(src.value().size());
- for (vector<boost::intrusive_ptr<node> >::size_type i = 0;
- i < src.value().size();
- ++i) {
- result[i] = this->clone_node(src.value()[i]);
- }
- dest.value(result);
- }
- };
-
- /**
- * @brief Construct.
- *
- * @param[in] impl_node a node in the @c PROTO implementation.
- * @param[in] impl_node_interface an interface of @p impl_node.
- */
- proto_node_metatype::
- is_target::is_target(node & impl_node,
- const std::string & impl_node_interface):
- impl_node(&impl_node),
- impl_node_interface(impl_node_interface)
- {}
-
- /**
- * @brief Construct.
- *
- * @param[in] from event source @c node.
- * @param[in] eventout @c eventOut of @p from.
- * @param[in] to event destination @c node.
- * @param[in] eventin @c eventIn of @p to.
- */
- proto_node_metatype::route::route(node & from,
- const std::string & eventout,
- node & to,
- const std::string & eventin):
- from(&from),
- eventout(eventout),
- to(&to),
- eventin(eventin)
- {}
-
- /**
- * @brief Construct.
- *
- * @param[in] node_metatype the proto_node_metatype that spawned the
- * @c proto_node_type.
- * @param[in] id @c node_type identifier.
- * @param[in] interfaces a subset of the interfaces supported by the
- * @p node_metatype.
- *
- * @exception unsupported_interface if an interface in @p interfaces is not
- * supported by the @p node_metatype.
- * @exception std::bad_alloc if memory allocation fails.
- */
- proto_node_type::proto_node_type(const proto_node_metatype & node_metatype,
- const std::string & id,
- const node_interface_set & interfaces)
- OPENVRML_THROW2(unsupported_interface, std::bad_alloc):
- node_type(node_metatype, id)
- {
- using std::find;
- using std::invalid_argument;
- for (node_interface_set::const_iterator interface_ = interfaces.begin();
- interface_ != interfaces.end();
- ++interface_) {
- node_interface_set::const_iterator pos =
- find(node_metatype.interfaces.begin(),
- node_metatype.interfaces.end(),
- *interface_);
- if (pos == node_metatype.interfaces.end()) {
- throw unsupported_interface(*interface_);
- }
- const bool succeeded = this->interfaces_.insert(*interface_).second;
- assert(succeeded);
- }
- }
-
- /**
- * @brief Destroy.
- */
- proto_node_type::~proto_node_type() OPENVRML_NOTHROW
- {}
-
- /**
- * @brief Interfaces.
- *
- * @return the interfaces.
- */
- const node_interface_set &
- proto_node_type::do_interfaces() const OPENVRML_NOTHROW
- {
- return this->interfaces_;
- }
-
- const boost::intrusive_ptr<node>
- proto_node_type::
- do_create_node(const boost::shared_ptr<openvrml::scope> & scope,
- const initial_value_map & initial_values) const
- OPENVRML_THROW1(std::bad_alloc)
- {
- return boost::intrusive_ptr<node>(
- new proto_node(*this, scope, initial_values));
- }
-
- /**
- * @internal
- *
- * @class abstract_proto_node::proto_eventin
- *
- * @brief @c PROTO @c eventIn handler class template.
- */
-
- /**
- * @typedef abstract_proto_node::proto_eventin::listeners
- *
- * @brief Set of event listeners.
- */
-
- /**
- * @var abstract_proto_node::proto_eventin::listeners abstract_proto_node::proto_eventin::listeners_
- *
- * @brief Set of event listeners to which events are delegated for
- * processing.
- */
-
- /**
- * @typedef abstract_proto_node::proto_eventin::field_value_type
- *
- * @brief Field value type.
- */
-
- /**
- * @typedef abstract_proto_node::proto_eventin::event_listener_type
- *
- * @brief Type of event listeners to which the instance delegates.
- */
-
- /**
- * @brief Construct.
- *
- * @param[in] node abstract_proto_node.
- */
- template <typename FieldValue>
- abstract_proto_node::proto_eventin<FieldValue>::
- proto_eventin(abstract_proto_node & node):
- node_event_listener(node),
- node_field_value_listener<FieldValue>(node)
- {}
-
- /**
- * @brief Destroy.
- */
- template <typename FieldValue>
- abstract_proto_node::proto_eventin<FieldValue>::~proto_eventin()
- OPENVRML_NOTHROW
- {}
-
- /**
- * @brief Process event.
- *
- * @param[in] value field value.
- * @param[in] timestamp the current time.
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- template <typename FieldValue>
- void
- abstract_proto_node::proto_eventin<FieldValue>::
- do_process_event(const FieldValue & value, const double timestamp)
- OPENVRML_THROW1(std::bad_alloc)
- {
- for (typename listeners::const_iterator listener =
- this->listeners_.begin();
- listener != this->listeners_.end();
- ++listener) {
- (*listener)->process_event(value, timestamp);
- }
- }
-
- /**
- * @brief The name of the associated @c eventIn.
- *
- * @return the name of the associated @c eventIn.
- */
- template <typename FieldValue>
- const std::string
- abstract_proto_node::proto_eventin<FieldValue>::do_eventin_id() const
- OPENVRML_NOTHROW
- {
- using boost::polymorphic_downcast;
- proto_node & n = *polymorphic_downcast<proto_node *>(&this->node());
- eventin_map_t::const_iterator pos =
- std::find_if(n.eventin_map.begin(), n.eventin_map.end(),
- proto_eventin_equal_to(*this));
- assert(pos != n.eventin_map.end());
- return pos->first;
- }
-
- /**
- * @brief Add a listener to delegate to. Corresponds to an @c IS statement.
- *
- * @param[in] listener an @c event_listener to delegate to.
- *
- * @return @c true if @p listener is added successfully; @c false
- * otherwise (if it already exists in the list of delegates).
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- template <typename FieldValue>
- bool
- abstract_proto_node::proto_eventin<FieldValue>::
- is(event_listener_type & listener)
- OPENVRML_THROW1(std::bad_alloc)
- {
- return this->listeners_.insert(&listener).second;
- }
-
- /**
- * @brief Factory function for @c proto_eventin<FieldValue> instances.
- *
- * @param[in] type @c field_value::type_id.
- * @param[in] node @c proto_node.
- *
- * @return a @c boost::shared_ptr to a @c proto_eventin<FieldValue>
- * instance.
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- boost::shared_ptr<event_listener>
- abstract_proto_node::create_eventin(const field_value::type_id type,
- abstract_proto_node & node)
- OPENVRML_THROW1(std::bad_alloc)
- {
- using boost::mpl::for_each;
- using openvrml_::field_value_types;
-
- boost::shared_ptr<openvrml::event_listener> result;
- for_each<field_value_types>(proto_eventin_creator(type, node, result));
- assert(result);
- return result;
- }
-
- /**
- * @internal
- *
- * @class abstract_proto_node::proto_eventout
- *
- * @brief @c PROTO @c eventOut handler class template.
- */
-
- /**
- * @internal
- *
- * @class abstract_proto_node::proto_eventout::listener_t
- *
- * @brief Listens for events emitted from @c node%s in the @c PROTO
- * implementation in order to propagate them out of the @c PROTO
- * instance.
- */
-
- /**
- * @var abstract_proto_node::proto_eventout & abstract_proto_node::proto_eventout::listener_t::emitter
- *
- * @brief Reference to the outer @c proto_eventout class.
- *
- * @todo It's annoying that we need to carry this around. Should
- * investigate the possibility of promoting all this stuff to
- * @c proto_eventout and have @c proto_eventout privately inherit
- * @c field_value_listener<FieldValue>.
- */
-
- /**
- * @var abstract_proto_node & abstract_proto_node::proto_eventout::listener_t::node
- *
- * @brief Reference to the @c abstract_proto_node instance.
- */
-
- /**
- * @var FieldValue abstract_proto_node::proto_eventout::listener_t::value
- *
- * @brief The value of the most recently emitted event.
- */
-
- /**
- * @brief Construct.
- *
- * @param[in] emitter @c proto_eventout.
- * @param[in] node @c abstract_proto_node.
- * @param[in] initial_value initial value (used for @c exposedFields).
- */
- template <typename FieldValue>
- abstract_proto_node::proto_eventout<FieldValue>::listener_t::
- listener_t(proto_eventout & emitter,
- abstract_proto_node & node,
- const FieldValue & initial_value):
- node_event_listener(node),
- node_field_value_listener<FieldValue>(node),
- emitter(emitter),
- node(node),
- value(initial_value)
- {}
-
- /**
- * @brief Destroy.
- */
- template <typename FieldValue>
- abstract_proto_node::proto_eventout<FieldValue>::listener_t::~listener_t()
- OPENVRML_NOTHROW
- {}
-
- /**
- * @brief Get the associated @c eventIn identifier.
- */
- template <typename FieldValue>
- const std::string
- abstract_proto_node::proto_eventout<FieldValue>::listener_t::
- do_eventin_id() const
- OPENVRML_NOTHROW
- {
- return "<proto_node::proto_eventout::listener_t>";
- }
-
- /**
- * @brief Process event.
- *
- * @param[in] value new value.
- * @param[in] timestamp the current time.
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- template<typename FieldValue>
- void
- abstract_proto_node::proto_eventout<FieldValue>::listener_t::
- do_process_event(const FieldValue & value, const double timestamp)
- OPENVRML_THROW1(std::bad_alloc)
- {
- if (timestamp > this->emitter.last_time()) {
- this->value = value;
- node::emit_event(this->emitter, timestamp);
- }
- }
-
- /**
- * @var abstract_proto_node::proto_eventout::listener_t abstract_proto_node::proto_eventout::listener
- *
- * @brief Listens for events emitted from nodes in the @c PROTO
- * implementation in order to propagate them out of the @c PROTO
- * instance.
- */
-
- /**
- * @typedef abstract_proto_node::proto_eventout<FieldValue>::field_value_type
- *
- * @brief Field value type.
- */
-
- /**
- * @typedef abstract_proto_node::proto_eventout<FieldValue>::event_emitter_type
- *
- * @brief Event emitter type.
- */
-
- /**
- * @typedef abstract_proto_node::proto_eventout<FieldValue>::event_listener_type
- *
- * @brief Event listener type.
- */
-
- /**
- * @brief Construct.
- *
- * @param[in] node @c abstract_proto_node.
- * @param[in] initial_value initial value. This is used by
- * @c proto_exposedfield<FieldValue>
- */
- template <typename FieldValue>
- abstract_proto_node::proto_eventout<FieldValue>::
- proto_eventout(abstract_proto_node & node,
- const FieldValue & initial_value):
- openvrml::event_emitter(this->listener.value),
- field_value_emitter<FieldValue>(this->listener.value),
- listener(*this, node, initial_value)
- {}
-
- /**
- * @brief Destroy.
- */
- template <typename FieldValue>
- abstract_proto_node::proto_eventout<FieldValue>::~proto_eventout()
- OPENVRML_NOTHROW
- {}
-
- /**
- * @brief Create an @c IS mapping.
- *
- * @param[in,out] emitter the @c event_emitter from a node in the @c PROTO
- * implementation.
- *
- * @return @c true if the @c IS mapping is created successfully; @c false
- * otherwise (i.e., if it already exists).
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- template <typename FieldValue>
- bool
- abstract_proto_node::proto_eventout<FieldValue>::
- is(event_emitter_type & emitter) OPENVRML_THROW1(std::bad_alloc)
- {
- return emitter.add(this->listener);
- }
-
- /**
- * @brief The name of the associated @c eventOut.
- *
- * @return the name of the associated @c eventOut.
- */
- template <typename FieldValue>
- const std::string
- abstract_proto_node::proto_eventout<FieldValue>::do_eventout_id() const
- OPENVRML_NOTHROW
- {
- abstract_proto_node & n = this->listener.node;
- eventout_map_t::const_iterator pos =
- std::find_if(n.eventout_map.begin(), n.eventout_map.end(),
- proto_eventout_equal_to(*this));
- assert(pos != n.eventout_map.end());
- return pos->first;
- }
-
- /**
- * @brief Factory function for @c proto_eventout<FieldValue> instances.
- *
- * @param[in] type @c field_value::type_id.
- * @param[in] node @c abstract_proto_node.
- *
- * @return a @c boost::shared_ptr to a @c proto_eventout<FieldValue>
- * instance.
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- boost::shared_ptr<event_emitter>
- abstract_proto_node::create_eventout(const field_value::type_id type,
- abstract_proto_node & node)
- OPENVRML_THROW1(std::bad_alloc)
- {
- using boost::mpl::for_each;
- using openvrml_::field_value_types;
-
- boost::shared_ptr<openvrml::event_emitter> result;
- for_each<field_value_types>(
- proto_eventout_creator(type, node, result));
- assert(result);
- return result;
- }
-
- /**
- * @internal
- *
- * @class proto_node::proto_exposedfield
- *
- * @brief @c PROTO @c exposedField handler class template.
- */
-
- /**
- * @brief Construct.
- *
- * @param[in] node proto_node.
- * @param[in] initial_value initial value.
- */
- template <typename FieldValue>
- proto_node::proto_exposedfield<FieldValue>::
- proto_exposedfield(abstract_proto_node & node,
- const FieldValue & initial_value):
- node_event_listener(node),
- openvrml::event_emitter(this->listener.value),
- proto_eventin<FieldValue>(node),
- proto_eventout<FieldValue>(node, initial_value)
- {}
-
- /**
- * @brief Destroy.
- */
- template <typename FieldValue>
- proto_node::proto_exposedfield<FieldValue>::~proto_exposedfield()
- OPENVRML_NOTHROW
- {}
-
- /**
- * @brief Process an event.
- *
- * @param[in] value event value.
- * @param[in] timestamp the current time.
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- template <typename FieldValue>
- void
- proto_node::proto_exposedfield<FieldValue>::
- do_process_event(const FieldValue & value, const double timestamp)
- OPENVRML_THROW1(std::bad_alloc)
- {
- this->proto_eventin<FieldValue>::do_process_event(value, timestamp);
- this->listener.value = value;
- node::emit_event(*this, timestamp);
- }
-
- /**
- * @brief Factory function for @c proto_exposedfield<FieldValue> instances.
- *
- * @param[in] type @c field_value::type_id.
- * @param[in] node @c proto_node.
- *
- * @return a @c boost::shared_ptr to a @c proto_exposedfield<FieldValue>
- * instance.
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- boost::shared_ptr<event_listener>
- proto_node::create_exposedfield(const field_value & initial_value,
- proto_node & node)
- OPENVRML_THROW1(std::bad_alloc)
- {
- using boost::mpl::for_each;
- using openvrml_::field_value_types;
-
- boost::shared_ptr<openvrml::event_listener> result;
- for_each<field_value_types>(proto_exposedfield_creator(initial_value,
- node,
- result));
- assert(result.get());
- return result;
- }
-
- /**
- * @brief Construct.
- *
- * @param[in] type @c node_type.
- * @param[in] scope @c scope.
- *
- * @exception std::bad_alloc if memory allocation fails.
- */
- proto_node::proto_node(const node_type & type,
- const boost::shared_ptr<openvrml::scope> & scope,
- const initial_value_map & initial_values)
- OPENVRML_THROW1(std::bad_alloc):
- abstract_proto_node(type, scope),
- proto_scope(scope)
- {
- const proto_node_metatype & node_metatype =
- static_cast<const proto_node_metatype &>(type.metatype());
-
- this->impl_nodes = proto_impl_cloner(node_metatype,
- initial_values,
- this->proto_scope).clone();
-
- //
- // Establish routes.
- //
- typedef proto_node_metatype::routes_t routes_t;
- for (routes_t::const_iterator route = node_metatype.routes.begin();
- route != node_metatype.routes.end();
- ++route) {
- // XXX
- // XXX It would be better to store the node_paths along with the
- // XXX route instead of rebuilding them every time we instantiate
- // XXX the PROTO.
- // XXX
- node_path_t path_to_from;
- assert(!node_metatype.impl_nodes.empty());
- path_getter(*route->from, path_to_from)
- .get_path_from(node_metatype.impl_nodes);
- assert(!path_to_from.empty());
- node * const from_node = resolve_node_path(path_to_from,
- this->impl_nodes);
- assert(from_node);
-
- node_path_t path_to_to;
- path_getter(*route->to, path_to_to)
- .get_path_from(node_metatype.impl_nodes);
- node * const to_node = resolve_node_path(path_to_to,
- this->impl_nodes);
- assert(to_node);
-
- try {
- add_route(*from_node, route->eventout,
- *to_node, route->eventin);
- } catch (unsupported_interface & ex) {
- OPENVRML_PRINT_EXCEPTION_(ex);
- } catch (field_v...
[truncated message content] |