display_factory.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2012, Willow Garage, Inc.
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the Willow Garage, Inc. nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 
00030 #include "rviz/display_group.h"
00031 
00032 #include "rviz/display_factory.h"
00033 
00034 #include <tinyxml.h>
00035 
00036 namespace rviz
00037 {
00038 
00039 static Display* newDisplayGroup()
00040 {
00041   return new DisplayGroup();
00042 }
00043 
00044 DisplayFactory::DisplayFactory()
00045   : PluginlibFactory<Display>( "rviz", "rviz::Display" )
00046 {
00047   addBuiltInClass( "rviz", "Group", "A container for Displays", &newDisplayGroup );
00048 }
00049 
00050 Display* DisplayFactory::makeRaw( const QString& class_id, QString* error_return )
00051 {
00052   Display* display = PluginlibFactory<Display>::makeRaw( class_id, error_return );
00053   if ( display )
00054   {
00055     display->setIcon( getIcon( class_id ));
00056   }
00057   return display;
00058 }
00059 
00060 QSet<QString> DisplayFactory::getMessageTypes( const QString& class_id )
00061 {
00062   // lookup in cache
00063   if ( message_type_cache_.find( class_id ) != message_type_cache_.end() )
00064   {
00065     return message_type_cache_[class_id];
00066   }
00067 
00068   // Always initialize cache as empty so if we don't find it, next time
00069   // we won't look for it anymore either.
00070   message_type_cache_[ class_id ] = QSet<QString>();
00071 
00072   // parse xml plugin description to find out message types of all displays in it.
00073   QString xml_file = getPluginManifestPath( class_id );
00074 
00075   if ( !xml_file.isEmpty() )
00076   {
00077     ROS_DEBUG_STREAM("Parsing " << xml_file.toStdString());
00078     TiXmlDocument document;
00079     document.LoadFile(xml_file.toStdString());
00080     TiXmlElement * config = document.RootElement();
00081     if (config == NULL)
00082     {
00083       ROS_ERROR("Skipping XML Document \"%s\" which had no Root Element.  This likely means the XML is malformed or missing.", xml_file.toStdString().c_str());
00084       return QSet<QString>();
00085     }
00086     if (config->ValueStr() != "library" &&
00087         config->ValueStr() != "class_libraries")
00088     {
00089       ROS_ERROR("The XML document \"%s\" given to add must have either \"library\" or \
00090           \"class_libraries\" as the root tag", xml_file.toStdString().c_str());
00091       return QSet<QString>();
00092     }
00093     //Step into the filter list if necessary
00094     if (config->ValueStr() == "class_libraries")
00095     {
00096       config = config->FirstChildElement("library");
00097     }
00098 
00099     TiXmlElement* library = config;
00100     while ( library != NULL)
00101     {
00102       TiXmlElement* class_element = library->FirstChildElement("class");
00103       while (class_element)
00104       {
00105         std::string derived_class = class_element->Attribute("type");
00106 
00107         std::string current_class_id;
00108         if(class_element->Attribute("name") != NULL)
00109         {
00110           current_class_id = class_element->Attribute("name");
00111           ROS_DEBUG("XML file specifies lookup name (i.e. magic name) = %s.", current_class_id.c_str());
00112         }
00113         else
00114         {
00115           ROS_DEBUG("XML file has no lookup name (i.e. magic name) for class %s, assuming class_id == real class name.", derived_class.c_str());
00116           current_class_id = derived_class;
00117         }
00118 
00119         QSet<QString> message_types;
00120         TiXmlElement* message_type = class_element->FirstChildElement("message_type");
00121 
00122         while ( message_type )
00123         {
00124           if ( message_type->GetText() )
00125           {
00126             const char* message_type_str = message_type->GetText();
00127             ROS_DEBUG_STREAM(current_class_id << " supports message type " << message_type_str );
00128 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
00129             message_types.insert( QString::fromAscii( message_type_str ) );
00130 #else
00131             message_types.insert( QString(message_type_str) );
00132 #endif
00133           }
00134           message_type = message_type->NextSiblingElement("message_type");
00135         }
00136 
00137         message_type_cache_[ QString::fromStdString(current_class_id) ] = message_types;
00138 
00139         //step to next class_element
00140         class_element = class_element->NextSiblingElement( "class" );
00141       }
00142       library = library->NextSiblingElement( "library" );
00143     }
00144   }
00145 
00146   // search cache again.
00147   if ( message_type_cache_.find( class_id ) != message_type_cache_.end() )
00148   {
00149     return message_type_cache_[class_id];
00150   }
00151 
00152   return QSet<QString>();
00153 }
00154 
00155 
00156 } // end namespace rviz


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Thu Jun 6 2019 18:02:15