diff --git a/doc/APIreference/functions.rst b/doc/APIreference/functions.rst
index 60fa14a1..81a3841a 100644
--- a/doc/APIreference/functions.rst
+++ b/doc/APIreference/functions.rst
@@ -4432,6 +4432,15 @@ mjs_asMaterial
Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
+.. _mjs_asPlugin:
+
+mjs_asPlugin
+~~~~~~~~~~~~
+
+.. mujoco-include:: mjs_asPlugin
+
+Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.
+
.. _AttributeSetters:
Attribute setters
diff --git a/doc/includes/references.h b/doc/includes/references.h
index c7669ec8..d1e11e55 100644
--- a/doc/includes/references.h
+++ b/doc/includes/references.h
@@ -1738,7 +1738,7 @@ typedef struct mjsOrientation_ { // alternative orientation specifiers
double euler[3]; // Euler angles
} mjsOrientation;
typedef struct mjsPlugin_ { // plugin specification
- mjsElement* instance; // element type
+ mjsElement* element; // element type
mjString* name; // name
mjString* instance_name; // instance name
int plugin_slot; // global registered slot number of the plugin
@@ -3622,6 +3622,7 @@ mjsHField* mjs_asHField(mjsElement* element);
mjsSkin* mjs_asSkin(mjsElement* element);
mjsTexture* mjs_asTexture(mjsElement* element);
mjsMaterial* mjs_asMaterial(mjsElement* element);
+mjsPlugin* mjs_asPlugin(mjsElement* element);
void mjs_setBuffer(mjByteVec* dest, const void* array, int size);
void mjs_setString(mjString* dest, const char* text);
void mjs_setStringVec(mjStringVec* dest, const char* text);
diff --git a/include/mujoco/mjspec.h b/include/mujoco/mjspec.h
index 90bc6c9a..807ef71c 100644
--- a/include/mujoco/mjspec.h
+++ b/include/mujoco/mjspec.h
@@ -181,7 +181,7 @@ typedef struct mjsOrientation_ { // alternative orientation specifiers
typedef struct mjsPlugin_ { // plugin specification
- mjsElement* instance; // element type
+ mjsElement* element; // element type
mjString* name; // name
mjString* instance_name; // instance name
int plugin_slot; // global registered slot number of the plugin
diff --git a/include/mujoco/mujoco.h b/include/mujoco/mujoco.h
index fbf9b151..cdc63388 100644
--- a/include/mujoco/mujoco.h
+++ b/include/mujoco/mujoco.h
@@ -1628,6 +1628,9 @@ MJAPI mjsTexture* mjs_asTexture(mjsElement* element);
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
+// Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.
+MJAPI mjsPlugin* mjs_asPlugin(mjsElement* element);
+
//---------------------------------- Attribute setters ---------------------------------------------
diff --git a/introspect/functions.py b/introspect/functions.py
index 838c1cff..f5f6cb08 100644
--- a/introspect/functions.py
+++ b/introspect/functions.py
@@ -10270,6 +10270,22 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
doc='Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.', # pylint: disable=line-too-long
)),
+ ('mjs_asPlugin',
+ FunctionDecl(
+ name='mjs_asPlugin',
+ return_type=PointerType(
+ inner_type=ValueType(name='mjsPlugin'),
+ ),
+ parameters=(
+ FunctionParameterDecl(
+ name='element',
+ type=PointerType(
+ inner_type=ValueType(name='mjsElement'),
+ ),
+ ),
+ ),
+ doc='Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.', # pylint: disable=line-too-long
+ )),
('mjs_setBuffer',
FunctionDecl(
name='mjs_setBuffer',
diff --git a/introspect/structs.py b/introspect/structs.py
index 149ebef0..cfaa5809 100644
--- a/introspect/structs.py
+++ b/introspect/structs.py
@@ -8565,7 +8565,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
declname='struct mjsPlugin_',
fields=(
StructFieldDecl(
- name='instance',
+ name='element',
type=PointerType(
inner_type=ValueType(name='mjsElement'),
),
diff --git a/python/mujoco/specs.cc b/python/mujoco/specs.cc
index 5dd4621e..04200af6 100644
--- a/python/mujoco/specs.cc
+++ b/python/mujoco/specs.cc
@@ -274,6 +274,18 @@ PYBIND11_MODULE(_specs, m) {
mjSpec.def("detach_body", [](MjSpec& self, raw::MjsBody& body) {
mjs_detachBody(self.ptr, &body);
});
+ mjSpec.def_property_readonly(
+ "plugins",
+ [](MjSpec& self) -> py::list {
+ py::list list;
+ raw::MjsElement* el = mjs_firstElement(self.ptr, mjOBJ_PLUGIN);
+ while (el) {
+ list.append(mjs_asPlugin(el));
+ el = mjs_nextElement(self.ptr, el);
+ }
+ return list;
+ },
+ py::return_value_policy::reference_internal);
mjSpec.def_property_readonly(
"actuators",
[](MjSpec& self) -> py::list {
@@ -900,12 +912,12 @@ PYBIND11_MODULE(_specs, m) {
// ============================= MJSPLUGIN ===================================
mjsPlugin.def_property(
"id",
- [](raw::MjsPlugin& self) -> int { return mjs_getId(self.instance); },
+ [](raw::MjsPlugin& self) -> int { return mjs_getId(self.element); },
[](raw::MjsPlugin& self, raw::MjsPlugin* other) {
- self.instance = other->instance;
+ self.element = other->element;
});
mjsPlugin.def("delete",
- [](raw::MjsPlugin& self) { mjs_delete(self.instance); });
+ [](raw::MjsPlugin& self) { mjs_delete(self.element); });
#include "specs.cc.inc"
} // PYBIND11_MODULE // NOLINT
diff --git a/python/mujoco/specs_test.py b/python/mujoco/specs_test.py
index fb3a1321..8ddaf8c1 100644
--- a/python/mujoco/specs_test.py
+++ b/python/mujoco/specs_test.py
@@ -690,5 +690,32 @@ class SpecsTest(absltest.TestCase):
):
spec.recompile(model, data)
+ def test_delete_unused_plugin(self):
+ spec = mujoco.MjSpec()
+ spec.from_string(textwrap.dedent("""
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ """))
+ plugin = spec.plugins[0]
+ self.assertIsNotNone(plugin)
+ plugin.delete()
+
+ model = spec.compile()
+ self.assertIsNotNone(model)
+ self.assertEqual(model.nplugin, 0)
+
if __name__ == '__main__':
absltest.main()
diff --git a/src/user/user_api.cc b/src/user/user_api.cc
index 4253f2ed..fe686dcb 100644
--- a/src/user/user_api.cc
+++ b/src/user/user_api.cc
@@ -471,7 +471,7 @@ mjsKey* mjs_addKey(mjSpec* s) {
mjsPlugin* mjs_addPlugin(mjSpec* s) {
mjCModel* modelC = static_cast(s->element);
mjCPlugin* plugin = modelC->AddPlugin();
- plugin->spec.instance = static_cast(plugin);
+ plugin->spec.element = static_cast(plugin);
return &plugin->spec;
}
@@ -887,6 +887,16 @@ mjsMaterial* mjs_asMaterial(mjsElement* element) {
+// return plugin given mjsElement
+mjsPlugin* mjs_asPlugin(mjsElement* element) {
+ if (element && element->elemtype == mjOBJ_PLUGIN) {
+ return &(static_cast(element)->spec);
+ }
+ return nullptr;
+}
+
+
+
// copy buffer to destination buffer
void mjs_setBuffer(mjByteVec* dest, const void* array, int size) {
const std::byte* buffer = static_cast(array);
@@ -995,7 +1005,7 @@ const double* mjs_getDouble(const mjDoubleVec* source, int* size) {
// set plugin attributes
void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes) {
- mjCPlugin* pluginC = static_cast(plugin->instance);
+ mjCPlugin* pluginC = static_cast(plugin->element);
std::map>* config_attribs =
reinterpret_cast>*>(attributes);
pluginC->config_attribs = std::move(*config_attribs);
diff --git a/src/user/user_api.h b/src/user/user_api.h
index 35799bad..a1b80dd2 100644
--- a/src/user/user_api.h
+++ b/src/user/user_api.h
@@ -296,6 +296,9 @@ MJAPI mjsTexture* mjs_asTexture(mjsElement* element);
// Safely cast an element as mjsMaterial, or return NULL if the element is not an mjsMaterial.
MJAPI mjsMaterial* mjs_asMaterial(mjsElement* element);
+// Safely cast an element as mjsPlugin, or return NULL if the element is not an mjsPlugin.
+MJAPI mjsPlugin* mjs_asPlugin(mjsElement* element);
+
//---------------------------------- Attribute setters ---------------------------------------------
diff --git a/src/user/user_composite.cc b/src/user/user_composite.cc
index 26c3a3db..d18ba94b 100644
--- a/src/user/user_composite.cc
+++ b/src/user/user_composite.cc
@@ -315,7 +315,7 @@ bool mjCComposite::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz)
// overwrite plugin name
if (plugin_instance_name.empty() && plugin.active) {
plugin_instance_name = "composite" + prefix;
- (static_cast(plugin.instance))->name = plugin_instance_name;
+ (static_cast(plugin.element))->name = plugin_instance_name;
}
// dispatch
@@ -714,7 +714,7 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix,
if (plugin.active) {
mjsPlugin* pplugin = &body->plugin;
pplugin->active = true;
- pplugin->instance = plugin.instance;
+ pplugin->element = plugin.element;
mjs_setString(pplugin->name, mjs_getString(plugin.name));
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
}
diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc
index 2243c1f5..4f5b4354 100644
--- a/src/user/user_flexcomp.cc
+++ b/src/user/user_flexcomp.cc
@@ -422,7 +422,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
// overwrite plugin name
if (plugin.active && plugin_instance_name.empty()) {
plugin_instance_name = "flexcomp_" + name;
- static_cast(plugin.instance)->name = plugin_instance_name;
+ static_cast(plugin.element)->name = plugin_instance_name;
}
// create bodies, construct flex vert and vertbody
@@ -440,7 +440,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
if (plugin.active) {
mjsPlugin* pplugin = &body->plugin;
pplugin->active = true;
- pplugin->instance = static_cast(plugin.instance);
+ pplugin->element = static_cast(plugin.element);
mjs_setString(pplugin->name, mjs_getString(plugin.name));
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
}
@@ -504,7 +504,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) {
if (plugin.active) {
mjsPlugin* pplugin = &pb->plugin;
pplugin->active = true;
- pplugin->instance = static_cast(plugin.instance);
+ pplugin->element = static_cast(plugin.element);
mjs_setString(pplugin->name, mjs_getString(plugin.name));
mjs_setString(pplugin->instance_name, plugin_instance_name.c_str());
}
diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc
index 2a398c6f..d06905b3 100644
--- a/src/user/user_mesh.cc
+++ b/src/user/user_mesh.cc
@@ -246,7 +246,7 @@ void mjCMesh::CopyFromSpec() {
facetexcoord_ = spec_facetexcoord_;
maxhullvert_ = spec.maxhullvert;
plugin.active = spec.plugin.active;
- plugin.instance = spec.plugin.instance;
+ plugin.element = spec.plugin.element;
plugin.name = spec.plugin.name;
plugin.instance_name = spec.plugin.instance_name;
@@ -270,7 +270,7 @@ mjCMesh::~mjCMesh() {
if (center_) mju_free(center_);
if (graph_) mju_free(graph_);
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
- model->DeleteElement(spec.plugin.instance);
+ model->DeleteElement(spec.plugin.element);
}
}
@@ -289,9 +289,9 @@ void mjCMesh::LoadSDF() {
name.c_str(), id);
}
- mjCPlugin* plugin_instance = static_cast(plugin.instance);
+ mjCPlugin* plugin_instance = static_cast(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
- plugin.instance = plugin_instance;
+ plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
throw mjCError(this, "plugin '%s' does not support signed distance fields", pplugin->name);
@@ -2919,9 +2919,9 @@ void mjCFlex::Compile(const mjVFS* vfs) {
useredge = VectorToString(edgeidx_);
for (const auto& vbodyid : vertbodyid) {
- if (model->Bodies()[vbodyid]->plugin.instance) {
+ if (model->Bodies()[vbodyid]->plugin.element) {
mjCPlugin* plugin_instance =
- static_cast(model->Bodies()[vbodyid]->plugin.instance);
+ static_cast(model->Bodies()[vbodyid]->plugin.element);
if (damping > 0) {
plugin_instance->config_attribs["damping"] = std::to_string(damping);
}
diff --git a/src/user/user_model.cc b/src/user/user_model.cc
index 1bfa3c70..b189677b 100644
--- a/src/user/user_model.cc
+++ b/src/user/user_model.cc
@@ -938,6 +938,8 @@ mjsElement* mjCModel::NextObject(mjsElement* object, mjtObj type) {
return GetNext(textures_, object);
case mjOBJ_MATERIAL:
return GetNext(materials_, object);
+ case mjOBJ_PLUGIN:
+ return GetNext(plugins_, object);
default:
return nullptr;
}
@@ -3932,7 +3934,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
std::vector> plugin_to_actuators(nplugin);
for (int i = 0; i < nu; ++i) {
if (actuators_[i]->plugin.active) {
- int actuator_plugin = static_cast(actuators_[i]->plugin.instance)->id;
+ int actuator_plugin = static_cast(actuators_[i]->plugin.element)->id;
m->actuator_plugin[i] = actuator_plugin;
plugin_to_actuators[actuator_plugin].push_back(i);
} else {
@@ -3942,7 +3944,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
for (int i = 0; i < nbody; ++i) {
if (bodies_[i]->plugin.active) {
- m->body_plugin[i] = static_cast(bodies_[i]->plugin.instance)->id;
+ m->body_plugin[i] = static_cast(bodies_[i]->plugin.element)->id;
} else {
m->body_plugin[i] = -1;
}
@@ -3950,7 +3952,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
for (int i = 0; i < ngeom; ++i) {
if (geoms_[i]->plugin.active) {
- m->geom_plugin[i] = static_cast(geoms_[i]->plugin.instance)->id;
+ m->geom_plugin[i] = static_cast(geoms_[i]->plugin.element)->id;
} else {
m->geom_plugin[i] = -1;
}
@@ -3959,7 +3961,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
std::vector> plugin_to_sensors(nplugin);
for (int i = 0; i < nsensor; ++i) {
if (sensors_[i]->type == mjSENS_PLUGIN) {
- int sensor_plugin = static_cast(sensors_[i]->plugin.instance)->id;
+ int sensor_plugin = static_cast(sensors_[i]->plugin.element)->id;
m->sensor_plugin[i] = sensor_plugin;
plugin_to_sensors[sensor_plugin].push_back(i);
} else {
diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc
index 22d00ae2..7d369998 100644
--- a/src/user/user_objects.cc
+++ b/src/user/user_objects.cc
@@ -959,7 +959,7 @@ void mjCBody::CopyFromSpec() {
*static_cast(this) = spec;
userdata_ = spec_userdata_;
plugin.active = spec.plugin.active;
- plugin.instance = spec.plugin.instance;
+ plugin.element = spec.plugin.element;
plugin.name = spec.plugin.name;
plugin.instance_name = spec.plugin.instance_name;
}
@@ -986,7 +986,7 @@ mjCBody::~mjCBody() {
lights.clear();
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
- model->DeleteElement(spec.plugin.instance);
+ model->DeleteElement(spec.plugin.element);
}
}
@@ -1669,9 +1669,9 @@ void mjCBody::Compile(void) {
name.c_str(), id);
}
- mjCPlugin* plugin_instance = static_cast(plugin.instance);
+ mjCPlugin* plugin_instance = static_cast(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
- plugin.instance = plugin_instance;
+ plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_PASSIVE)) {
throw mjCError(this, "plugin '%s' does not support passive forces", pplugin->name);
@@ -2132,7 +2132,7 @@ mjCGeom::mjCGeom(const mjCGeom& other) {
mjCGeom::~mjCGeom() {
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
- model->DeleteElement(spec.plugin.instance);
+ model->DeleteElement(spec.plugin.element);
}
}
@@ -2176,7 +2176,7 @@ void mjCGeom::CopyFromSpec() {
meshname_ = spec_meshname_;
material_ = spec_material_;
plugin.active = spec.plugin.active;
- plugin.instance = spec.plugin.instance;
+ plugin.element = spec.plugin.element;
plugin.name = spec.plugin.name;
plugin.instance_name = spec.plugin.instance_name;
}
@@ -2913,9 +2913,9 @@ void mjCGeom::Compile(void) {
this, "neither 'plugin' nor 'instance' is specified for geom");
}
- mjCPlugin* plugin_instance = static_cast(plugin.instance);
+ mjCPlugin* plugin_instance = static_cast(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
- plugin.instance = plugin_instance;
+ plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
throw mjCError(this, "plugin '%s' does not support sign distance fields", pplugin->name);
@@ -5554,7 +5554,7 @@ mjCActuator::mjCActuator(const mjCActuator& other) {
mjCActuator::~mjCActuator() {
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
- model->DeleteElement(spec.plugin.instance);
+ model->DeleteElement(spec.plugin.element);
}
}
@@ -5640,7 +5640,7 @@ void mjCActuator::CopyFromSpec() {
refsite_ = spec_refsite_;
slidersite_ = spec_slidersite_;
plugin.active = spec.plugin.active;
- plugin.instance = spec.plugin.instance;
+ plugin.element = spec.plugin.element;
plugin.name = spec.plugin.name;
plugin.instance_name = spec.plugin.instance_name;
}
@@ -5869,9 +5869,9 @@ void mjCActuator::Compile(void) {
name.c_str(), id);
}
- mjCPlugin* plugin_instance = static_cast(plugin.instance);
+ mjCPlugin* plugin_instance = static_cast(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
- plugin.instance = plugin_instance;
+ plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_ACTUATOR)) {
throw mjCError(this, "plugin '%s' does not support actuators", pplugin->name);
@@ -5916,7 +5916,7 @@ mjCSensor::mjCSensor(const mjCSensor& other) {
mjCSensor::~mjCSensor() {
if (spec.plugin.active && spec.plugin.instance_name->empty()) {
- model->DeleteElement(spec.plugin.instance);
+ model->DeleteElement(spec.plugin.element);
}
}
@@ -5968,7 +5968,7 @@ void mjCSensor::CopyFromSpec() {
objname_ = spec_objname_;
refname_ = spec_refname_;
plugin.active = spec.plugin.active;
- plugin.instance = spec.plugin.instance;
+ plugin.element = spec.plugin.element;
plugin.name = spec.plugin.name;
plugin.instance_name = spec.plugin.instance_name;
}
@@ -6373,9 +6373,9 @@ void mjCSensor::Compile(void) {
// resolve plugin instance, or create one if using the "plugin" attribute shortcut
{
- mjCPlugin* plugin_instance = static_cast(plugin.instance);
+ mjCPlugin* plugin_instance = static_cast(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
- plugin.instance = plugin_instance;
+ plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_SENSOR)) {
throw mjCError(this, "plugin '%s' does not support sensors", pplugin->name);
diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc
index ed6e4339..d5813799 100644
--- a/src/xml/xml_native_reader.cc
+++ b/src/xml/xml_native_reader.cc
@@ -2767,7 +2767,7 @@ void mjXReader::OnePlugin(XMLElement* elem, mjsPlugin* plugin) {
mjs_setString(plugin->name, name.c_str());
mjs_setString(plugin->instance_name, instance_name.c_str());
if (instance_name.empty()) {
- plugin->instance = mjs_addPlugin(spec)->instance;
+ plugin->element = mjs_addPlugin(spec)->element;
ReadPluginConfigs(elem, plugin);
} else {
spec->hasImplicitPluginElem = true;
diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc
index 92ddd08c..0643e4e9 100644
--- a/src/xml/xml_native_writer.cc
+++ b/src/xml/xml_native_writer.cc
@@ -827,8 +827,8 @@ void mjXWriter::OnePlugin(XMLElement* elem, const mjsPlugin* plugin) {
} else {
WriteAttrTxt(elem, "plugin", plugin_name);
const mjpPlugin* pplugin = mjp_getPluginAtSlot(
- static_cast(plugin->instance)->spec.plugin_slot);
- const char* c = &(static_cast(plugin->instance)->flattened_attributes[0]);
+ static_cast(plugin->element)->spec.plugin_slot);
+ const char* c = &(static_cast(plugin->element)->flattened_attributes[0]);
for (int i = 0; i < pplugin->nattribute; ++i) {
string value(c);
if (!value.empty()) {
diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc
index b27f26e2..39811a30 100644
--- a/test/user/user_api_test.cc
+++ b/test/user/user_api_test.cc
@@ -147,7 +147,7 @@ TEST_F(PluginTest, ActivatePlugin) {
// associate plugin to body
mjsBody* body = mjs_addBody(mjs_findBody(spec, "world"), 0);
mjs_setString(body->plugin.name, plugin_name.c_str());
- body->plugin.instance = mjs_addPlugin(spec)->instance;
+ body->plugin.element = mjs_addPlugin(spec)->element;
body->plugin.active = true;
mjsGeom* geom = mjs_addGeom(body, 0);
geom->type = mjGEOM_BOX;
@@ -191,7 +191,7 @@ TEST_F(PluginTest, DeletePlugin) {
mjsActuator* actuator = mjs_addActuator(spec, 0);
mjs_setString(actuator->target, "j1");
mjs_setString(actuator->plugin.name, plugin_name.c_str());
- actuator->plugin.instance = mjs_addPlugin(spec)->instance;
+ actuator->plugin.element = mjs_addPlugin(spec)->element;
actuator->plugin.active = true;
actuator->trntype = mjTRN_JOINT;