display_factory.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "rviz/display_group.h"
31 
32 #include "rviz/display_factory.h"
33 
34 #include <tinyxml.h>
35 
36 namespace rviz
37 {
38 
40 {
41  return new DisplayGroup();
42 }
43 
45  : PluginlibFactory<Display>( "rviz", "rviz::Display" )
46 {
47  addBuiltInClass( "rviz", "Group", "A container for Displays", &newDisplayGroup );
48 }
49 
50 Display* DisplayFactory::makeRaw( const QString& class_id, QString* error_return )
51 {
52  Display* display = PluginlibFactory<Display>::makeRaw( class_id, error_return );
53  if ( display )
54  {
55  display->setIcon( getIcon( class_id ));
56  }
57  return display;
58 }
59 
60 QSet<QString> DisplayFactory::getMessageTypes( const QString& class_id )
61 {
62  // lookup in cache
63  if ( message_type_cache_.find( class_id ) != message_type_cache_.end() )
64  {
65  return message_type_cache_[class_id];
66  }
67 
68  // Always initialize cache as empty so if we don't find it, next time
69  // we won't look for it anymore either.
70  message_type_cache_[ class_id ] = QSet<QString>();
71 
72  // parse xml plugin description to find out message types of all displays in it.
73  QString xml_file = getPluginManifestPath( class_id );
74 
75  if ( !xml_file.isEmpty() )
76  {
77  ROS_DEBUG_STREAM("Parsing " << xml_file.toStdString());
78  TiXmlDocument document;
79  document.LoadFile(xml_file.toStdString());
80  TiXmlElement * config = document.RootElement();
81  if (config == NULL)
82  {
83  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());
84  return QSet<QString>();
85  }
86  if (config->ValueStr() != "library" &&
87  config->ValueStr() != "class_libraries")
88  {
89  ROS_ERROR("The XML document \"%s\" given to add must have either \"library\" or \
90  \"class_libraries\" as the root tag", xml_file.toStdString().c_str());
91  return QSet<QString>();
92  }
93  //Step into the filter list if necessary
94  if (config->ValueStr() == "class_libraries")
95  {
96  config = config->FirstChildElement("library");
97  }
98 
99  TiXmlElement* library = config;
100  while ( library != NULL)
101  {
102  TiXmlElement* class_element = library->FirstChildElement("class");
103  while (class_element)
104  {
105  std::string derived_class = class_element->Attribute("type");
106 
107  std::string current_class_id;
108  if(class_element->Attribute("name") != NULL)
109  {
110  current_class_id = class_element->Attribute("name");
111  ROS_DEBUG("XML file specifies lookup name (i.e. magic name) = %s.", current_class_id.c_str());
112  }
113  else
114  {
115  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());
116  current_class_id = derived_class;
117  }
118 
119  QSet<QString> message_types;
120  TiXmlElement* message_type = class_element->FirstChildElement("message_type");
121 
122  while ( message_type )
123  {
124  if ( message_type->GetText() )
125  {
126  const char* message_type_str = message_type->GetText();
127  ROS_DEBUG_STREAM(current_class_id << " supports message type " << message_type_str );
128 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
129  message_types.insert( QString::fromAscii( message_type_str ) );
130 #else
131  message_types.insert( QString(message_type_str) );
132 #endif
133  }
134  message_type = message_type->NextSiblingElement("message_type");
135  }
136 
137  message_type_cache_[ QString::fromStdString(current_class_id) ] = message_types;
138 
139  //step to next class_element
140  class_element = class_element->NextSiblingElement( "class" );
141  }
142  library = library->NextSiblingElement( "library" );
143  }
144  }
145 
146  // search cache again.
147  if ( message_type_cache_.find( class_id ) != message_type_cache_.end() )
148  {
149  return message_type_cache_[class_id];
150  }
151 
152  return QSet<QString>();
153 }
154 
155 
156 } // end namespace rviz
virtual void setIcon(const QIcon &icon)
Set the Display&#39;s icon.
Definition: display.cpp:401
#define NULL
Definition: global.h:37
virtual Type * makeRaw(const QString &class_id, QString *error_return=NULL)
Instantiate and return a instance of a subclass of Type using our pluginlib::ClassLoader.
config
virtual void addBuiltInClass(const QString &package, const QString &name, const QString &description, Display *(*factory_function)())
virtual QIcon getIcon(const QString &class_id) const
virtual QSet< QString > getMessageTypes(const QString &class_id)
Get all supported message types for the given class id.
A Display object which stores other Displays as children.
Definition: display_group.h:47
virtual Display * makeRaw(const QString &class_id, QString *error_return=NULL)
Overridden from PluginlibFactory<Display> to set the icon of the Display.
QMap< QString, QSet< QString > > message_type_cache_
#define ROS_DEBUG_STREAM(args)
static Display * newDisplayGroup()
#define ROS_ERROR(...)
virtual QString getPluginManifestPath(const QString &class_id) const
#define ROS_DEBUG(...)


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Wed Aug 28 2019 04:01:50