Skip to content

Commit c119eaf

Browse files
author
Davide Faconti
committed
hide visibility of tinyxml2
Use the Pimpl idiom to hide the specific implementation of XMLParser
1 parent 2a2c34c commit c119eaf

File tree

4 files changed

+58
-43
lines changed

4 files changed

+58
-43
lines changed

3rdparty/tinyXML2/tinyxml2.h

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,11 @@ distribution.
6464
# pragma warning(disable: 4251)
6565
#endif
6666

67+
// Do NOT export. This version is meant to be linked statically only.
6768
#ifdef _WIN32
68-
# ifdef TINYXML2_EXPORT
69-
# define TINYXML2_LIB __declspec(dllexport)
70-
# elif defined(TINYXML2_IMPORT)
71-
# define TINYXML2_LIB __declspec(dllimport)
72-
# else
73-
# define TINYXML2_LIB
74-
# endif
75-
#elif __GNUC__ >= 4
76-
# define TINYXML2_LIB __attribute__((visibility("default")))
77-
#else
7869
# define TINYXML2_LIB
70+
#elif __GNUC__ >= 4
71+
# define TINYXML2_LIB __attribute__((visibility("hidden")))
7972
#endif
8073

8174

CMakeLists.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@ if(catkin_FOUND)
2121
message(STATUS "------------------------------------------")
2222

2323
catkin_package(
24-
INCLUDE_DIRS include
24+
INCLUDE_DIRS include # do not include "3rdparty" here
2525
LIBRARIES behavior_tree_core
2626
)
27-
include_directories(3rdparty)
28-
27+
2928
else(catkin_FOUND)
3029

3130
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)

include/behavior_tree_core/xml_parsing.h

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22
#define XML_PARSING_BT_H
33

44
#include "behavior_tree_core/bt_factory.h"
5-
#include "tinyXML2/tinyxml2.h"
65

76
namespace BT
87
{
98
class XMLParser
109
{
1110
public:
12-
XMLParser(const BehaviorTreeFactory& factory) : factory_(factory)
13-
{
14-
}
11+
XMLParser(const BehaviorTreeFactory& factory);
12+
13+
~XMLParser();
14+
15+
XMLParser(const XMLParser& other) = delete;
16+
XMLParser& operator=(const XMLParser& other) = delete;
1517

1618
void loadFromFile(const std::string& filename);
1719

@@ -25,14 +27,10 @@ class XMLParser
2527
TreeNode::Ptr instantiateTree(std::vector<TreeNode::Ptr>& nodes);
2628

2729
private:
28-
//method to visit each node of a tree
29-
TreeNode::Ptr treeParsing(const tinyxml2::XMLElement* root_element,
30-
const NodeBuilder& node_builder, std::vector<TreeNode::Ptr>& nodes,
31-
const TreeNode::Ptr& root_parent);
3230

33-
tinyxml2::XMLDocument doc_;
31+
struct Pimpl;
32+
Pimpl* _p;
3433

35-
const BehaviorTreeFactory& factory_;
3634
};
3735

3836
struct Tree

src/xml_parsing.cpp

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,32 +11,57 @@
1111
*/
1212

1313
#include "behavior_tree_core/xml_parsing.h"
14+
#include "tinyXML2/tinyxml2.h"
15+
1416
#include <functional>
1517

1618
namespace BT
1719
{
18-
using namespace tinyxml2;
20+
21+
struct XMLParser::Pimpl
22+
{
23+
TreeNode::Ptr treeParsing(const tinyxml2::XMLElement* root_element,
24+
const NodeBuilder& node_builder,
25+
std::vector<TreeNode::Ptr>& nodes,
26+
const TreeNode::Ptr& root_parent);
27+
28+
tinyxml2::XMLDocument doc;
29+
30+
const BehaviorTreeFactory& factory;
31+
32+
Pimpl(const BehaviorTreeFactory &fact): factory(fact) {}
33+
};
34+
35+
36+
XMLParser::XMLParser(const BehaviorTreeFactory &factory) : _p( new Pimpl(factory) )
37+
{
38+
}
39+
40+
XMLParser::~XMLParser()
41+
{
42+
delete _p;
43+
}
1944

2045
void XMLParser::loadFromFile(const std::string& filename)
2146
{
22-
XMLError err = doc_.LoadFile(filename.c_str());
47+
tinyxml2::XMLError err = _p->doc.LoadFile(filename.c_str());
2348

2449
if (err)
2550
{
2651
char buffer[200];
27-
sprintf(buffer, "Error parsing the XML: %s", XMLDocument::ErrorIDToName(err));
52+
sprintf(buffer, "Error parsing the XML: %s", tinyxml2::XMLDocument::ErrorIDToName(err));
2853
throw std::runtime_error(buffer);
2954
}
3055
}
3156

3257
void XMLParser::loadFromText(const std::string& xml_text)
3358
{
34-
XMLError err = doc_.Parse(xml_text.c_str(), xml_text.size());
59+
tinyxml2::XMLError err = _p->doc.Parse(xml_text.c_str(), xml_text.size());
3560

3661
if (err)
3762
{
3863
char buffer[200];
39-
sprintf(buffer, "Error parsing the XML: %s", XMLDocument::ErrorIDToName(err));
64+
sprintf(buffer, "Error parsing the XML: %s", tinyxml2::XMLDocument::ErrorIDToName(err));
4065
throw std::runtime_error(buffer);
4166
}
4267
}
@@ -45,7 +70,7 @@ bool XMLParser::verifyXML(std::vector<std::string>& error_messages) const
4570
{
4671
error_messages.clear();
4772

48-
if (doc_.Error())
73+
if (_p->doc.Error())
4974
{
5075
error_messages.emplace_back("The XML was not correctly loaded");
5176
return false;
@@ -64,7 +89,7 @@ bool XMLParser::verifyXML(std::vector<std::string>& error_messages) const
6489
is_valid = false;
6590
};
6691

67-
auto ChildrenCount = [](const XMLElement* parent_node) {
92+
auto ChildrenCount = [](const tinyxml2::XMLElement* parent_node) {
6893
int count = 0;
6994
for (auto node = parent_node->FirstChildElement(); node != nullptr;
7095
node = node->NextSiblingElement())
@@ -76,7 +101,7 @@ bool XMLParser::verifyXML(std::vector<std::string>& error_messages) const
76101

77102
//-----------------------------
78103

79-
const XMLElement* xml_root = doc_.RootElement();
104+
const tinyxml2::XMLElement* xml_root = _p->doc.RootElement();
80105

81106
if (!xml_root || !strEqual(xml_root->Name(), "root"))
82107
{
@@ -129,9 +154,9 @@ bool XMLParser::verifyXML(std::vector<std::string>& error_messages) const
129154
//-------------------------------------------------
130155

131156
// function to be called recursively
132-
std::function<void(const XMLElement*)> recursiveStep;
157+
std::function<void(const tinyxml2::XMLElement*)> recursiveStep;
133158

134-
recursiveStep = [&](const XMLElement* node) {
159+
recursiveStep = [&](const tinyxml2::XMLElement* node) {
135160
const int children_count = ChildrenCount(node);
136161
const char* name = node->Name();
137162
if (strEqual(name, "Decorator"))
@@ -192,7 +217,7 @@ bool XMLParser::verifyXML(std::vector<std::string>& error_messages) const
192217
{
193218
// Last resort: MAYBE used ID as element name?
194219
bool found = false;
195-
for (const auto& model : factory_.manifests())
220+
for (const auto& model : _p->factory.manifests())
196221
{
197222
if (model.registration_ID == name)
198223
{
@@ -274,15 +299,15 @@ TreeNode::Ptr XMLParser::instantiateTree(std::vector<TreeNode::Ptr>& nodes)
274299
}
275300

276301
//--------------------------------------
277-
XMLElement* xml_root = doc_.RootElement();
302+
tinyxml2::XMLElement* xml_root = _p->doc.RootElement();
278303

279304
std::string main_tree_ID;
280305
if (xml_root->Attribute("main_tree_to_execute"))
281306
{
282307
main_tree_ID = xml_root->Attribute("main_tree_to_execute");
283308
}
284309

285-
std::map<std::string, XMLElement*> bt_roots;
310+
std::map<std::string, tinyxml2::XMLElement*> bt_roots;
286311

287312
int tree_count = 0;
288313

@@ -309,7 +334,7 @@ TreeNode::Ptr XMLParser::instantiateTree(std::vector<TreeNode::Ptr>& nodes)
309334
NodeBuilder node_builder = [&](const std::string& ID, const std::string& name,
310335
const NodeParameters& params,
311336
TreeNode::Ptr parent) -> TreeNode::Ptr {
312-
TreeNode::Ptr child_node = factory_.instantiateTreeNode(ID, name, params);
337+
TreeNode::Ptr child_node = _p->factory.instantiateTreeNode(ID, name, params);
313338
nodes.push_back(child_node);
314339
if (parent)
315340
{
@@ -329,20 +354,20 @@ TreeNode::Ptr XMLParser::instantiateTree(std::vector<TreeNode::Ptr>& nodes)
329354
if (subtree_node)
330355
{
331356
auto subtree_elem = bt_roots[name]->FirstChildElement();
332-
treeParsing(subtree_elem, node_builder, nodes, child_node);
357+
_p->treeParsing(subtree_elem, node_builder, nodes, child_node);
333358
}
334359
return child_node;
335360
};
336361
//--------------------------------------
337362

338363
auto root_element = bt_roots[main_tree_ID]->FirstChildElement();
339-
return treeParsing(root_element, node_builder, nodes, TreeNode::Ptr());
364+
return _p->treeParsing(root_element, node_builder, nodes, TreeNode::Ptr());
340365
}
341366

342-
TreeNode::Ptr BT::XMLParser::treeParsing(const XMLElement* root_element,
343-
const NodeBuilder& node_builder,
344-
std::vector<TreeNode::Ptr>& nodes,
345-
const TreeNode::Ptr& root_parent)
367+
TreeNode::Ptr BT::XMLParser::Pimpl::treeParsing(const tinyxml2::XMLElement* root_element,
368+
const NodeBuilder& node_builder,
369+
std::vector<TreeNode::Ptr>& nodes,
370+
const TreeNode::Ptr& root_parent)
346371
{
347372
using namespace tinyxml2;
348373

0 commit comments

Comments
 (0)