From: Braden M. <br...@us...> - 2005-11-07 06:55:30
|
Update of /cvsroot/openvrml/openvrml/src/libopenvrml/openvrml In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9556/src/libopenvrml/openvrml Modified Files: Vrml97Parser.g browser.cpp Log Message: Support parsing nodes from unrecognized EXTERNPROTOs. Index: browser.cpp =================================================================== RCS file: /cvsroot/openvrml/openvrml/src/libopenvrml/openvrml/browser.cpp,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** browser.cpp 3 Nov 2005 07:48:05 -0000 1.91 --- browser.cpp 7 Nov 2005 06:55:21 -0000 1.92 *************** *** 162,201 **** ! /** ! * @internal ! * ! * @brief A <code>PROTO</code> instance node. ! * ! * Like a typical node implementation, <code>proto_node</code>s have a ! * many-to-one relationship with the ! * <code>proto_node::proto_node_type</code> instance that creates them. And [...1005 lines suppressed...] + assert(pos->second); + return *pos->second; + } + + openvrml::event_emitter & + externproto_node::do_event_emitter(const std::string & id) + throw (openvrml::unsupported_interface) + { + eventout_map_t::const_iterator pos = this->eventout_map.find(id); + if (pos == this->eventout_map.end()) { + throw openvrml::unsupported_interface( + this->type(), openvrml::node_interface::eventout_id, id); + } + assert(pos->second); + return *pos->second; + } + + class OPENVRML_LOCAL default_navigation_info : public openvrml::navigation_info_node { Index: Vrml97Parser.g =================================================================== RCS file: /cvsroot/openvrml/openvrml/src/libopenvrml/openvrml/Vrml97Parser.g,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** Vrml97Parser.g 30 Oct 2005 03:20:17 -0000 1.34 --- Vrml97Parser.g 7 Nov 2005 06:55:21 -0000 1.35 *************** *** 935,948 **** options { defaultErrorHandler=false; } { openvrml::node_interface_set interfaces; ! openvrml::mfstring url_list; ! boost::shared_ptr<node_type> node_type; } : KEYWORD_EXTERNPROTO id:ID LBRACKET (externInterfaceDeclaration[interfaces])* RBRACKET ! url_list=externprotoUrlList { ! for (size_t i = 0; i < url_list.value().size(); ++i) { ! boost::shared_ptr<openvrml::node_class> node_class = ! browser.node_class_map_.find(url_list.value()[i]); if (node_class) { node_type = node_class->create_type(id->getText(), --- 935,955 ---- options { defaultErrorHandler=false; } { + using std::string; + using std::vector; + using boost::shared_ptr; + openvrml::node_interface_set interfaces; ! openvrml::mfstring uri_list; ! shared_ptr<node_type> node_type; } : KEYWORD_EXTERNPROTO id:ID LBRACKET (externInterfaceDeclaration[interfaces])* RBRACKET ! uri_list=externprotoUrlList { ! const vector<string> & alt_uris = uri_list.value(); ! for (vector<string>::const_iterator uri = alt_uris.begin(); ! uri != alt_uris.end(); ! ++uri) { ! const shared_ptr<openvrml::node_class> node_class = ! browser.node_class_map_.find(*uri); if (node_class) { node_type = node_class->create_type(id->getText(), *************** *** 951,972 **** } } ! // ! // If we weren't able to create a node_type, that means that we ! // don't already have a node_class for the node. Currently we only ! // support referring to existing node_classes with EXTERNPROTO; ! // adding new node_classes via EXTERNPROTO is not supported. In ! // practice, this means that the ordinary way of using EXTERNPROTOs ! // in VRML worlds will fail. ! // ! if (node_type) { ! if (!scope->add_type(node_type)) { ! using antlr::SemanticException; ! throw SemanticException("Node type \"" + node_type->id() ! + "\" has already been defined in " ! " this scope.", ! this->uri, ! id->getLine(), ! id->getColumn()); } } } --- 958,996 ---- } } ! ! if (!node_type) { ! const shared_ptr<node_class> externproto_class( ! new externproto_node_class(browser, alt_uris)); ! ! for (vector<string>::const_iterator uri = alt_uris.begin(); ! uri != alt_uris.end(); ! ++uri) { ! browser.node_class_map_.insert(*uri, externproto_class); } + + node_type = externproto_class->create_type(id->getText(), + interfaces); + // + // Hack alert. If we get an empty list of URIs for the + // EXTERNPROTO implementation, we have nothing to put in + // browser::node_class_map_. That means that we'd wind up + // with no owning pointer to the node class except for the + // one in this scope (which is about to go away). So, we + // store an owning pointer in the externproto_node_type. + // + boost::dynamic_pointer_cast<externproto_node_type>(node_type) + ->set_owning_ptr_to_class(externproto_class); + } + + assert(node_type); + + if (!scope->add_type(node_type)) { + using antlr::SemanticException; + throw SemanticException("Node type \"" + node_type->id() + + "\" has already been defined in " + + "this scope.", + this->uri, + id->getLine(), + id->getColumn()); } } |