From 0e05c8b2d291ff98571d9bddf146d138855e8ef7 Mon Sep 17 00:00:00 2001 From: Joseph Mirabel <jmirabel@laas.fr> Date: Mon, 14 Dec 2020 18:38:55 +0100 Subject: [PATCH] Update serialization functions. --- include/hpp/manipulation/device.hh | 2 + include/hpp/manipulation/graph/graph.hh | 4 + include/hpp/manipulation/serialization.hh | 98 +++++++++++------------ src/device.cc | 11 ++- src/steering-method/graph.cc | 2 +- 5 files changed, 59 insertions(+), 58 deletions(-) diff --git a/include/hpp/manipulation/device.hh b/include/hpp/manipulation/device.hh index 1841997..2586170 100644 --- a/include/hpp/manipulation/device.hh +++ b/include/hpp/manipulation/device.hh @@ -50,6 +50,8 @@ namespace hpp { return shPtr; } + DevicePtr_t self () const { return self_.lock(); } + /// Print object in a stream virtual std::ostream& print (std::ostream& os) const; diff --git a/include/hpp/manipulation/graph/graph.hh b/include/hpp/manipulation/graph/graph.hh index 0cef13e..ade3266 100644 --- a/include/hpp/manipulation/graph/graph.hh +++ b/include/hpp/manipulation/graph/graph.hh @@ -52,6 +52,8 @@ namespace hpp { static GraphPtr_t create(const std::string& name, DevicePtr_t robot, const ProblemPtr_t& problem); + GraphPtr_t self () const { return wkPtr_.lock(); } + /// Create and insert a state selector inside the graph. StateSelectorPtr_t createStateSelector (const std::string& name); @@ -301,4 +303,6 @@ namespace hpp { } // namespace hpp +BOOST_CLASS_EXPORT_KEY(hpp::manipulation::graph::Graph) + #endif // HPP_MANIPULATION_GRAPH_GRAPH_HH diff --git a/include/hpp/manipulation/serialization.hh b/include/hpp/manipulation/serialization.hh index 0711fc4..cfb1835 100644 --- a/include/hpp/manipulation/serialization.hh +++ b/include/hpp/manipulation/serialization.hh @@ -34,10 +34,33 @@ namespace hpp { namespace serialization { -struct archive_graph_wrapper { - manipulation::graph::GraphPtr_t graph; - virtual ~archive_graph_wrapper() {} -}; +template<typename Archive> +manipulation::graph::GraphPtr_t getGraphFromArchive(Archive& ar, const std::string& name) +{ + auto* har = hpp::serialization::cast(&ar); + if (!har || !har->contains(name)) + throw std::runtime_error("Cannot deserialize edges with a provided graph with correct name."); + return har->template get<manipulation::graph::Graph>(name, true)->self(); +} + +template<class Archive, class GraphCompT> +inline void serializeGraphComponent(Archive & ar, boost::shared_ptr<GraphCompT>& c, const unsigned int version) +{ + (void) version; + + std::size_t id; + std::string name; + if (Archive::is_saving::value) { + id = (c ? c->id() : -1); + if (c && c->parentGraph()) name = c->parentGraph()->name(); + } + ar & BOOST_SERIALIZATION_NVP(id); + ar & BOOST_SERIALIZATION_NVP(name); + if (!Archive::is_saving::value) { + auto graph = getGraphFromArchive(ar, name); + c = HPP_DYNAMIC_PTR_CAST(GraphCompT, graph->get(id).lock()); + } +} } // namespace manipulation } // namespace hpp @@ -51,64 +74,32 @@ namespace serialization { template<class Archive> inline void serialize(Archive & ar, hpp::manipulation::graph::GraphPtr_t& g, const unsigned int version) { - using hpp::serialization::archive_graph_wrapper; - using namespace hpp::manipulation::graph; + using hpp::serialization::getGraphFromArchive; (void) version; - std::size_t id; - if (Archive::is_saving::value) id = g->id(); - ar & BOOST_SERIALIZATION_NVP(id); - if (!Archive::is_saving::value) { - archive_graph_wrapper* agw = dynamic_cast<archive_graph_wrapper*>(&ar); - if (agw == NULL) - throw std::runtime_error("Cannot deserialize edges with a archive_graph_wrapper"); - g = agw->graph; - } + std::string name; + if (Archive::is_saving::value) name = g->name(); + ar & BOOST_SERIALIZATION_NVP(name); + if (!Archive::is_saving::value) + g = getGraphFromArchive(ar, name); } template<class Archive> inline void serialize(Archive & ar, hpp::manipulation::graph::EdgePtr_t& e, const unsigned int version) { - using hpp::serialization::archive_graph_wrapper; - using namespace hpp::manipulation::graph; - (void) version; - - std::size_t id; - if (Archive::is_saving::value) id = (e ? e->id() : -1); - ar & BOOST_SERIALIZATION_NVP(id); - if (!Archive::is_saving::value) { - archive_graph_wrapper* agw = dynamic_cast<archive_graph_wrapper*>(&ar); - if (agw == NULL) - throw std::runtime_error("Cannot deserialize edges with a archive_graph_wrapper"); - GraphComponentPtr_t gc = agw->graph->get(id).lock(); - e = HPP_DYNAMIC_PTR_CAST(Edge, gc); - } + hpp::serialization::serializeGraphComponent (ar, e, version); } template<class Archive> inline void serialize(Archive & ar, hpp::manipulation::graph::StatePtr_t& s, const unsigned int version) { - using hpp::serialization::archive_graph_wrapper; - using namespace hpp::manipulation::graph; - (void) version; - - std::size_t id; - if (Archive::is_saving::value) id = (s ? s->id() : -1); - ar & BOOST_SERIALIZATION_NVP(id); - if (!Archive::is_saving::value) { - archive_graph_wrapper* agw = dynamic_cast<archive_graph_wrapper*>(&ar); - if (agw == NULL) - throw std::runtime_error("Cannot deserialize edges with a archive_graph_wrapper"); - GraphComponentPtr_t gc = agw->graph->get(id).lock(); - s = HPP_DYNAMIC_PTR_CAST(State, gc); - } + hpp::serialization::serializeGraphComponent (ar, s, version); } template<class Archive> inline void serialize(Archive & ar, hpp::manipulation::graph::EdgeWkPtr_t& e, const unsigned int version) { - using namespace hpp::manipulation::graph; - EdgePtr_t e_ = e.lock(); + auto e_ = e.lock(); serialize(ar, e_, version); e = e_; } @@ -116,8 +107,7 @@ inline void serialize(Archive & ar, hpp::manipulation::graph::EdgeWkPtr_t& e, co template<class Archive> inline void serialize(Archive & ar, hpp::manipulation::graph::StateWkPtr_t& s, const unsigned int version) { - using namespace hpp::manipulation::graph; - StatePtr_t s_ = s.lock(); + auto s_ = s.lock(); serialize(ar, s_, version); s = s_; } @@ -126,18 +116,20 @@ template<class Archive> inline void load (Archive& ar, hpp::manipulation::DevicePtr_t& d, const unsigned int version) { load<Archive, hpp::manipulation::Device> (ar, d, version); - using hpp::serialization::archive_device_wrapper; - archive_device_wrapper* adw = dynamic_cast<archive_device_wrapper*>(&ar); - if (adw) d = boost::dynamic_pointer_cast<hpp::manipulation::Device>(adw->device); + auto* har = hpp::serialization::cast(&ar); + if (d && har && har->contains(d->name())) + d = har->template getChildClass<hpp::pinocchio::Device, hpp::manipulation::Device>(d->name(), true)->self(); } template<class Archive> inline void load (Archive& ar, hpp::manipulation::DeviceWkPtr_t& d, const unsigned int version) { load<Archive, hpp::manipulation::Device> (ar, d, version); - using hpp::serialization::archive_device_wrapper; - archive_device_wrapper* adw = dynamic_cast<archive_device_wrapper*>(&ar); - if (adw) d = boost::dynamic_pointer_cast<hpp::manipulation::Device>(adw->device); + auto* har = hpp::serialization::cast(&ar); + auto dd = d.lock(); + if (!dd) return; + if (har && har->contains(dd->name())) + d = har->template getChildClass<hpp::pinocchio::Device, hpp::manipulation::Device>(dd->name(), true)->self(); } } // namespace serialization } // namespace boost diff --git a/src/device.cc b/src/device.cc index 665301d..09b8b4a 100644 --- a/src/device.cc +++ b/src/device.cc @@ -139,13 +139,16 @@ namespace hpp { template<class Archive> void Device::serialize(Archive & ar, const unsigned int version) { - using hpp::serialization::archive_device_wrapper; using namespace boost::serialization; - (void) version; + auto* har = hpp::serialization::cast(&ar); + ar & make_nvp("base", base_object<pinocchio::HumanoidRobot>(*this)); - archive_device_wrapper* adw = dynamic_cast<archive_device_wrapper*>(&ar); - bool written = (adw == NULL); + + // TODO we should throw if a pinocchio::Device instance with name name_ + // and not of type manipulation::Device is found. + bool written = (!har || + har->template getChildClass<pinocchio::Device, Device>(name_, false) != this); ar & BOOST_SERIALIZATION_NVP(written); if (written) { ar & BOOST_SERIALIZATION_NVP(self_); diff --git a/src/steering-method/graph.cc b/src/steering-method/graph.cc index 0e47f49..f7d778c 100644 --- a/src/steering-method/graph.cc +++ b/src/steering-method/graph.cc @@ -44,7 +44,7 @@ namespace hpp { GraphPtr_t Graph::create (const core::ProblemConstPtr_t& problem) { - assert(HPP_DYNAMIC_PTR_CASE (const Problem, problem)); + assert(HPP_DYNAMIC_PTR_CAST (const Problem, problem)); ProblemConstPtr_t p = HPP_STATIC_PTR_CAST(const Problem, problem); Graph* ptr = new Graph (p); GraphPtr_t shPtr (ptr); -- GitLab