From dfe8e45101382a6afb579550259bdb15e21764ef Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Tue, 1 Oct 2024 09:13:43 -0700 Subject: [PATCH] Namespace plugin instances when attaching. Fixes #2112. PiperOrigin-RevId: 681045462 Change-Id: I2c945c5405fcb91e0f9a1b0b1e94f68d174c84ee --- src/user/user_mesh.cc | 3 +++ src/user/user_model.cc | 1 + src/user/user_objects.cc | 22 ++++++++++++++++++++++ src/user/user_objects.h | 1 + test/user/user_api_test.cc | 12 +++++++++--- 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index d03fc42b..f04cf1ab 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -230,6 +230,9 @@ void mjCMesh::NameSpace(const mjCModel* m) { if (meshdir_.empty()) { meshdir_ = FilePath(m->spec_meshdir_); } + if (!plugin_instance_name.empty()) { + plugin_instance_name = m->prefix + plugin_instance_name + m->suffix; + } } diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 1a6bfbd7..afa3e251 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -341,6 +341,7 @@ mjCModel& mjCModel::operator+=(const mjCModel& other) { std::unordered_map plugin_map; for (const auto& plugin : other.plugins_) { plugins_.push_back(new mjCPlugin(*plugin)); + plugins_.back()->NameSpace(&other); plugin_map[plugin] = plugins_.back(); } mapplugin(plugin_map, bodies_); diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 833a8106..9b05702f 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -1016,6 +1016,9 @@ void mjCBody::NameSpace_(const mjCModel* m, bool propagate) { if (!classname.empty() && m != model) { classname = m->prefix + classname + m->suffix; } + if (!plugin_instance_name.empty()) { + plugin_instance_name = m->prefix + plugin_instance_name + m->suffix; + } for (auto& body : bodies) { body->prefix = m->prefix; @@ -2222,6 +2225,9 @@ void mjCGeom::NameSpace(const mjCModel* m) { if (!spec_meshname_.empty() && model != m) { spec_meshname_ = m->prefix + spec_meshname_ + m->suffix; } + if (!plugin_instance_name.empty()) { + plugin_instance_name = m->prefix + plugin_instance_name + m->suffix; + } } @@ -5649,6 +5655,9 @@ void mjCActuator::NameSpace(const mjCModel* m) { if (!name.empty()) { name = m->prefix + name + m->suffix; } + if (!plugin_instance_name.empty()) { + plugin_instance_name = m->prefix + plugin_instance_name + m->suffix; + } spec_target_ = m->prefix + spec_target_ + m->suffix; spec_refsite_ = m->prefix + spec_refsite_ + m->suffix; spec_slidersite_ = m->prefix + spec_slidersite_ + m->suffix; @@ -5979,6 +5988,9 @@ void mjCSensor::NameSpace(const mjCModel* m) { if (!name.empty()) { name = m->prefix + name + m->suffix; } + if (!plugin_instance_name.empty()) { + plugin_instance_name = m->prefix + plugin_instance_name + m->suffix; + } prefix = m->prefix; suffix = m->suffix; } @@ -6919,6 +6931,7 @@ mjCPlugin::mjCPlugin(mjCModel* _model) { mjCPlugin::mjCPlugin(const mjCPlugin& other) { *this = other; + id = -1; } @@ -6934,6 +6947,15 @@ mjCPlugin& mjCPlugin::operator=(const mjCPlugin& other) { +void mjCPlugin::NameSpace(const mjCModel* m) { + mjCBase::NameSpace(m); + if (!instance_name.empty()) { + instance_name = m->prefix + instance_name + m->suffix; + } +} + + + // compiler void mjCPlugin::Compile(void) { const mjpPlugin* plugin = mjp_getPluginAtSlot(spec.plugin_slot); diff --git a/src/user/user_objects.h b/src/user/user_objects.h index ea5b6f71..7a252133 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -1422,6 +1422,7 @@ class mjCPlugin : public mjCPlugin_ { private: void Compile(void); // compiler + void NameSpace(const mjCModel* m); }; diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index a4a7d425..123f6f73 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -243,10 +243,16 @@ TEST_F(PluginTest, AttachPlugin) { EXPECT_THAT(attachment_frame, NotNull()); mjs_attachBody(attachment_frame, mjs_findBody(spec_2, "body"), "child-", ""); - mjModel* model = mj_compile(spec_1, nullptr); - EXPECT_THAT(model, NotNull()); + mjModel* model_1 = mj_compile(spec_1, nullptr); + EXPECT_THAT(model_1, NotNull()); - mj_deleteModel(model); + // attach it a second time to test namespacing + mjs_attachBody(attachment_frame, mjs_findBody(spec_2, "body"), "copy-", ""); + mjModel* model_2 = mj_compile(spec_1, nullptr); + EXPECT_THAT(model_2, NotNull()); + + mj_deleteModel(model_1); + mj_deleteModel(model_2); mj_deleteSpec(spec_1); mj_deleteSpec(spec_2); }