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 <tinyxml2.h>
35 
36 namespace rviz
37 {
39 {
40  return new DisplayGroup();
41 }
42 
44 {
45  addBuiltInClass("rviz", "Group", "A container for Displays", &newDisplayGroup);
46 }
47 
48 Display* DisplayFactory::makeRaw(const QString& class_id, QString* error_return)
49 {
50  Display* display = PluginlibFactory<Display>::makeRaw(class_id, error_return);
51  if (display)
52  {
53  display->setIcon(getIcon(class_id));
54  }
55  return display;
56 }
57 
58 QSet<QString> DisplayFactory::getMessageTypes(const QString& class_id)
59 {
60  // lookup in cache
61  if (message_type_cache_.find(class_id) != message_type_cache_.end())
62  {
63  return message_type_cache_[class_id];
64  }
65 
66  // Always initialize cache as empty so if we don't find it, next time
67  // we won't look for it anymore either.
68  message_type_cache_[class_id] = QSet<QString>();
69 
70  // parse xml plugin description to find out message types of all displays in it.
71  QString xml_file = getPluginManifestPath(class_id);
72 
73  if (!xml_file.isEmpty())
74  {
75  ROS_DEBUG_STREAM("Parsing " << xml_file.toStdString());
76  tinyxml2::XMLDocument document;
77  document.LoadFile(xml_file.toStdString().c_str());
78  tinyxml2::XMLElement* config = document.RootElement();
79  if (config == nullptr)
80  {
81  ROS_ERROR("Skipping XML Document \"%s\" which had no Root Element. This likely means the XML is "
82  "malformed or missing.",
83  xml_file.toStdString().c_str());
84  return QSet<QString>();
85  }
86  if (std::string(config->Name()) != "library" && std::string(config->Name()) != "class_libraries")
87  {
88  ROS_ERROR("The XML document \"%s\" given to add must have either \"library\" or \
89  \"class_libraries\" as the root tag",
90  xml_file.toStdString().c_str());
91  return QSet<QString>();
92  }
93  // Step into the filter list if necessary
94  if (std::string(config->Name()) == "class_libraries")
95  {
96  config = config->FirstChildElement("library");
97  }
98 
99  tinyxml2::XMLElement* library = config;
100  while (library != nullptr)
101  {
102  tinyxml2::XMLElement* 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") != nullptr)
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 == "
116  "real class name.",
117  derived_class.c_str());
118  current_class_id = derived_class;
119  }
120 
121  QSet<QString> message_types;
122  tinyxml2::XMLElement* message_type = class_element->FirstChildElement("message_type");
123 
124  while (message_type)
125  {
126  if (message_type->GetText())
127  {
128  const char* message_type_str = message_type->GetText();
129  ROS_DEBUG_STREAM(current_class_id << " supports message type " << message_type_str);
130 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
131  message_types.insert(QString::fromAscii(message_type_str));
132 #else
133  message_types.insert(QString(message_type_str));
134 #endif
135  }
136  message_type = message_type->NextSiblingElement("message_type");
137  }
138 
139  message_type_cache_[QString::fromStdString(current_class_id)] = message_types;
140 
141  // step to next class_element
142  class_element = class_element->NextSiblingElement("class");
143  }
144  library = library->NextSiblingElement("library");
145  }
146  }
147 
148  // search cache again.
149  if (message_type_cache_.find(class_id) != message_type_cache_.end())
150  {
151  return message_type_cache_[class_id];
152  }
153 
154  return QSet<QString>();
155 }
156 
157 
158 } // end namespace rviz
Display * makeRaw(const QString &class_id, QString *error_return=nullptr) override
Overridden from PluginlibFactory<Display> to set the icon of the Display.
config
virtual void addBuiltInClass(const QString &package, const QString &name, const QString &description, Display *(*factory_function)())
virtual QSet< QString > getMessageTypes(const QString &class_id)
Get all supported message types for the given class id.
virtual QString getPluginManifestPath(const QString &class_id) const
A Display object which stores other Displays as children.
Definition: display_group.h:47
#define ROS_DEBUG_STREAM(args)
QMap< QString, QSet< QString > > message_type_cache_
Type * makeRaw(const QString &class_id, QString *error_return=nullptr) override
Instantiate and return a instance of a subclass of Type using our pluginlib::ClassLoader.
static Display * newDisplayGroup()
#define ROS_ERROR(...)
QIcon getIcon(const QString &class_id) const override
void setIcon(const QIcon &icon) override
Set the Display&#39;s icon.
Definition: display.cpp:404
#define ROS_DEBUG(...)


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust
autogenerated on Sat May 27 2023 02:06:24