From: Braden M. <br...@us...> - 2005-11-26 20:18:22
|
Update of /cvsroot/openvrml/openvrml/src/libopenvrml/openvrml In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv15986/src/libopenvrml/openvrml Modified Files: Vrml97Parser.g browser.cpp browser.h Log Message: Exposed means to add and retrieve node_classes from the browser's node_class map as part of openvrml::browser's public interface. Index: browser.cpp =================================================================== RCS file: /cvsroot/openvrml/openvrml/src/libopenvrml/openvrml/browser.cpp,v retrieving revision 1.94 retrieving revision 1.95 diff -C2 -d -r1.94 -r1.95 *** browser.cpp 26 Nov 2005 08:14:47 -0000 1.94 --- browser.cpp 26 Nov 2005 20:18:09 -0000 1.95 *************** *** 3603,3606 **** --- 3603,3611 ---- }; + inline bool relative(const uri & id) + { + return id.scheme().empty(); + } + uri::grammar::grammar(uri & uri_ref) throw (): uri_ref(uri_ref) *************** *** 3973,3978 **** using std::string; ! assert(this->scheme().empty()); ! assert(!absolute_uri.scheme().empty()); string result = absolute_uri.scheme() + ':'; --- 3978,3983 ---- using std::string; ! assert(relative(*this)); ! assert(!relative(absolute_uri)); string result = absolute_uri.scheme() + ':'; *************** *** 4491,4494 **** --- 4496,4594 ---- /** + * @class openvrml::node_class_id + * + * @brief Identifier for <code>node_class</code>es. + * + * <code>node_class</code> identifiers take the following form: + * + * <pre> + * absolute-uri ['#' proto-id ['#' proto-id [...]]] + * </pre> + * + * A <code>node_class</code> identifier is basically like an absolute URI; + * except the fragment identifier syntax has been extended to support referring + * to nested <code>PROTO</code>s. + * + * For example, supposing the following VRML world resides at + * <code>%http://example.com/example.wrl</code>: + * + * <pre> + * #VRML V2.0 utf8 + * + * PROTO Outer [] { + * PROTO Inner [] { Group {} } + * Group {} + * } + * </pre> + * + * The <code>node_class_id</code> string for <code>Outer</code> would be + * <code>http://example.com/example.wrl#Outer</code>; and for + * <code>Inner</code>, + * <code>http://example.com/example.wrl#Outer#Inner</code>. + */ + + /** + * @internal + * + * @var std::string openvrml::node_class_id::id_ + * + * @brief The identifier string. + */ + + /** + * @brief Construct from a <code>const char *</code>. + * + * @param id the identifier. + * + * @exception std::invalid_argument if @p id is not a valid + * <code>node_class</code> identifier. + * @exception std::bad_alloc if memory allocation fails. + * + * @todo Need to make sure the fragment part is valid. + */ + openvrml::node_class_id::node_class_id(const char * id) + throw (std::invalid_argument, std::bad_alloc): + id_(id) + { + if (relative(uri(this->id_))) { + throw std::invalid_argument('<' + this->id_ + "> is not a valid " + "node_class identifier"); + } + } + + /** + * @brief Construct from a <code>std::string</code>. + * + * @param id the identifier. + * + * @exception std::invalid_argument if @p id is not a valid + * <code>node_class</code> identifier. + * @exception std::bad_alloc if memory allocation fails. + * + * @todo Need to make sure the fragment part is valid. + */ + openvrml::node_class_id::node_class_id(const std::string & id) + throw (std::invalid_argument, std::bad_alloc): + id_(id) + { + if (relative(uri(this->id_))) { + throw std::invalid_argument('<' + this->id_ + "> is not a valid " + "node_class identifier"); + } + } + + /** + * @brief Convert to a <code>std::string</code>. + * + * @return the <code>node_class</code> identifier as a + * <code>std::string</code>. + */ + openvrml::node_class_id::operator std::string() const + { + return this->id_; + } + + + /** * @class openvrml::browser * *************** *** 4619,4623 **** openvrml::browser::node_class_map:: insert(const std::string & id, ! const boost::shared_ptr<node_class> & node_class) { boost::mutex::scoped_lock lock(this->mutex_); --- 4719,4723 ---- openvrml::browser::node_class_map:: insert(const std::string & id, ! const boost::shared_ptr<openvrml::node_class> & node_class) { boost::mutex::scoped_lock lock(this->mutex_); *************** *** 4626,4629 **** --- 4726,4742 ---- /** + * @brief Remove a <code>node_class</code>. + * + * @param id the implementation identifier. + * + * @return @c true if a <code>node_class</code> is removed; @c false otherwise. + */ + bool openvrml::browser::node_class_map::remove(const std::string & id) + { + boost::mutex::scoped_lock lock(this->mutex_); + return this->map_.erase(id) > 0; + } + + /** * @brief Find a <code>node_class</code>. * *************** *** 4639,4643 **** return (pos != this->map_.end()) ? pos->second ! : boost::shared_ptr<node_class>(); } --- 4752,4756 ---- return (pos != this->map_.end()) ? pos->second ! : boost::shared_ptr<openvrml::node_class>(); } *************** *** 6691,6694 **** --- 6804,6852 ---- /** + * @brief Add a <code>node_class</code>. + * + * If a <code>node_class</code> identified by @p id has already been added to + * the browser, it will be replaced. + * + * @warning If <code>std::bad_alloc</code> is thrown here, the + * <code>browser</code>'s <code>node_class</code> map is left in an + * unknown state. In all likelihood any preexisting entry in the map + * with the same implementation identifier as @p id will have been + * removed. + * + * @param id a <code>node_class</code> identifier. + * @param nc a <code>shared_ptr</code> to a <code>node_class</code> + * + * @exception std::invalid_argument if @p nc is null. + * @exception std::bad_alloc if memory allocation fails. + */ + void + openvrml::browser:: + add_node_class(const node_class_id & id, + const boost::shared_ptr<openvrml::node_class> & nc) + throw (std::invalid_argument, std::bad_alloc) + { + if (!nc) { + throw std::invalid_argument("cannot add null node_class pointer"); + } + this->node_class_map_.remove(id); // Remove any existing entry. + this->node_class_map_.insert(id, nc); + } + + /** + * @brief Get the <code>node_class</code> corresponding to @p id. + * + * @param id a <code>node_class</code> identifier. + * + * @return the <code>node_class</code> corresponding to @p id; or a null + * pointer if no such <code>node_class</code> exists. + */ + const boost::shared_ptr<openvrml::node_class> + openvrml::browser::node_class(const node_class_id & id) const throw () + { + return this->node_class_map_.find(id); + } + + /** * @brief Get the root nodes for the browser. * *************** *** 7926,7930 **** throw (bad_path, std::bad_alloc) { ! assert(relative_uri.scheme().empty()); using std::string; --- 8084,8088 ---- throw (bad_path, std::bad_alloc) { ! assert(relative(relative_uri)); using std::string; *************** *** 8304,8308 **** const uri urlElement(url[i]); const string value = ! urlElement.scheme().empty() ? urlElement.resolve_against(uri(this->url())) : urlElement; --- 8462,8466 ---- const uri urlElement(url[i]); const string value = ! relative(urlElement) ? urlElement.resolve_against(uri(this->url())) : urlElement; *************** *** 8353,8357 **** // absolute file URL. // ! const uri absolute_uri = !test_uri.scheme().empty() ? test_uri : (!this->parent() && this->url().empty()) --- 8511,8515 ---- // absolute file URL. // ! const uri absolute_uri = !relative(test_uri) ? test_uri : (!this->parent() && this->url().empty()) Index: browser.h =================================================================== RCS file: /cvsroot/openvrml/openvrml/src/libopenvrml/openvrml/browser.h,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** browser.h 15 Nov 2005 00:28:43 -0000 1.34 --- browser.h 26 Nov 2005 20:18:09 -0000 1.35 *************** *** 171,174 **** --- 171,186 ---- + class OPENVRML_API node_class_id { + std::string id_; + + public: + node_class_id(const char * id) + throw (std::invalid_argument, std::bad_alloc); + node_class_id(const std::string & id) + throw (std::invalid_argument, std::bad_alloc); + operator std::string() const; + }; + + class viewer; class scene; *************** *** 195,201 **** void init(viewpoint_node * initial_viewpoint, double timestamp); ! const boost::shared_ptr<node_class> insert(const std::string & id, ! const boost::shared_ptr<node_class> & node_class); const boost::shared_ptr<node_class> --- 207,215 ---- void init(viewpoint_node * initial_viewpoint, double timestamp); ! const boost::shared_ptr<openvrml::node_class> insert(const std::string & id, ! const boost::shared_ptr<openvrml::node_class> & node_class); ! ! bool remove(const std::string & id); const boost::shared_ptr<node_class> *************** *** 249,252 **** --- 263,272 ---- virtual ~browser() throw (); + void add_node_class(const node_class_id & id, + const boost::shared_ptr<openvrml::node_class> & nc) + throw (std::invalid_argument, std::bad_alloc); + const boost::shared_ptr<openvrml::node_class> + node_class(const node_class_id & id) const throw (); + const std::vector<boost::intrusive_ptr<node> > & root_nodes() const throw (); Index: Vrml97Parser.g =================================================================== RCS file: /cvsroot/openvrml/openvrml/src/libopenvrml/openvrml/Vrml97Parser.g,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** Vrml97Parser.g 7 Nov 2005 06:55:21 -0000 1.35 --- Vrml97Parser.g 26 Nov 2005 20:18:09 -0000 1.36 *************** *** 691,695 **** ; ! proto[openvrml::browser & browser, const boost::shared_ptr<openvrml::scope> & scope] options { defaultErrorHandler=false; } { --- 691,696 ---- ; ! proto[openvrml::browser & browser, ! const boost::shared_ptr<openvrml::scope> & scope] options { defaultErrorHandler=false; } { *************** *** 732,738 **** do { impl_id = '#' + proto_scope->id() + impl_id; ! } while ((proto_scope = proto_scope->parent())); impl_id = scope->id() + impl_id; ! browser.node_class_map_.insert(impl_id, node_class); // --- 733,739 ---- do { impl_id = '#' + proto_scope->id() + impl_id; ! } while ((proto_scope = proto_scope->parent())->parent()); impl_id = scope->id() + impl_id; ! browser.add_node_class(impl_id, node_class); // *************** *** 951,955 **** ++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(), --- 952,956 ---- ++uri) { const shared_ptr<openvrml::node_class> node_class = ! browser.node_class(*uri); if (node_class) { node_type = node_class->create_type(id->getText(), *************** *** 966,970 **** uri != alt_uris.end(); ++uri) { ! browser.node_class_map_.insert(*uri, externproto_class); } --- 967,971 ---- uri != alt_uris.end(); ++uri) { ! browser.add_node_class(*uri, externproto_class); } |