AutoAPMS
Streamlining behaviors in ROS 2
Loading...
Searching...
No Matches
resource.hpp
1// Copyright 2024 Robin Müller
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <map>
18#include <set>
19#include <string>
20#include <type_traits>
21#include <vector>
22
23#include "auto_apms_util/container.hpp"
24#include "auto_apms_util/exceptions.hpp"
25#include "auto_apms_util/string.hpp"
26#include "pluginlib/class_loader.hpp"
27
28namespace auto_apms_util
29{
30
33
44std::set<std::string> getPackagesWithResourceType(
45 const std::string & resource_type, const std::set<std::string> & exclude_packages = {});
46
56std::set<std::string> getPackagesWithPluginResources(const std::set<std::string> & exclude_packages = {});
57
69std::string getPluginXMLPath(const std::string & package);
70
82std::vector<std::string> collectPluginXMLPaths(const std::set<std::string> & exclude_packages = {});
83
85
86// clang-format off
109// clang-format on
110template <typename BaseT>
111class PluginClassLoader : public pluginlib::ClassLoader<BaseT>
112{
113public:
129 const std::string & base_package, const std::string & base_class,
130 const std::set<std::string> & exclude_packages = {});
131
156 const std::string & base_package, const std::string & base_class,
157 const std::set<std::string> & exclude_packages = {},
158 const std::map<std::string, std::string> & reserved_names = {});
159
164 std::map<std::string, std::string> getClassPackageMap();
165};
166
167// #####################################################################################################################
168// ################################ DEFINITIONS ##############################################
169// #####################################################################################################################
170
171template <typename BaseT>
173 const std::string & base_package, const std::string & base_class, const std::set<std::string> & exclude_packages)
174: pluginlib::ClassLoader<BaseT>(base_package, base_class, "", collectPluginXMLPaths(exclude_packages))
175{
176}
177
178template <typename BaseT>
180 const std::string & base_package, const std::string & base_class, const std::set<std::string> & exclude_packages,
181 const std::map<std::string, std::string> & reserved_names)
182{
183 std::map<std::string, std::vector<std::string>> packages_for_class_name;
184 const std::set<std::string> packages = getPackagesWithPluginResources(exclude_packages);
185 for (const auto & package : packages) {
186 auto single_package_loader =
187 pluginlib::ClassLoader<BaseT>(base_package, base_class, "", {getPluginXMLPath(package)});
188 for (const auto & class_name : single_package_loader.getDeclaredClasses()) {
189 packages_for_class_name[class_name].push_back(package);
190 }
191 }
192
193 // Reserved class names are considered as registered
194 for (const auto & [class_name, package] : reserved_names) {
195 packages_for_class_name[class_name].push_back(package);
196 }
197
198 // Determine if there are duplicate class names
199 std::vector<std::string> error_details;
200 for (const auto & [class_name, packages] : packages_for_class_name) {
201 if (packages.size() > 1) {
202 error_details.push_back(
203 "- Class '" + class_name + "' found in packages ['" + auto_apms_util::join(packages, "', '") + "'].");
204 }
205 }
206 if (!error_details.empty()) {
207 throw exceptions::ResourceError(
208 "Ambiguous class names found! PluginClassLoader (Base: " + base_class +
209 ") created with makeUnambiguousPluginClassLoader() won't register resources from packages "
210 "that use already existing lookup names. Found the following duplicates:\n" +
211 auto_apms_util::join(error_details, "\n"));
212 }
213 return {base_package, base_class, exclude_packages};
214}
215
216template <typename BaseT>
217inline std::map<std::string, std::string> PluginClassLoader<BaseT>::getClassPackageMap()
218{
219 std::map<std::string, std::string> map;
220 for (const std::string & class_name : this->getDeclaredClasses()) {
221 map[class_name] = this->getClassPackage(class_name);
222 }
223 return map;
224}
225
226} // namespace auto_apms_util
static PluginClassLoader makeUnambiguousPluginClassLoader(const std::string &base_package, const std::string &base_class, const std::set< std::string > &exclude_packages={}, const std::map< std::string, std::string > &reserved_names={})
Parse all associated plugin manifest files registered with the ament resource index and instantiate a...
Definition resource.hpp:179
std::map< std::string, std::string > getClassPackageMap()
Retrieve a map that contains information about which package a plugin class belongs to.
Definition resource.hpp:217
PluginClassLoader(const std::string &base_package, const std::string &base_class, const std::set< std::string > &exclude_packages={})
Standard PluginClassLoader constructor.
Definition resource.hpp:172
std::vector< std::string > collectPluginXMLPaths(const std::set< std::string > &exclude_packages={})
Collect the paths of plugins.xml manifest files generated by AutoAPMS.
Definition resource.cpp:65
std::string getPluginXMLPath(const std::string &package)
Get the path of a specific plugins.xml manifest file generated by AutoAPMS.
Definition resource.cpp:46
std::set< std::string > getPackagesWithResourceType(const std::string &resource_type, const std::set< std::string > &exclude_packages={})
Get a list of all package names that register a certain type of ament_index resources.
Definition resource.cpp:28
std::set< std::string > getPackagesWithPluginResources(const std::set< std::string > &exclude_packages={})
Get a list of all package names that register AutoAPMS plugin resources.
Definition resource.cpp:41
Fundamental helper classes and utility functions.