Do not expose plugin_slot.

PiperOrigin-RevId: 683215401
Change-Id: Ic64f7221ed83ca3b0c8cca16eb680ea67c67b564
This commit is contained in:
Alessio Quaglino
2024-10-07 09:36:36 -07:00
committed by Copybara-Service
parent 66faba9aa5
commit 1f9dca8bc4
17 changed files with 50 additions and 49 deletions
+1 -1
View File
@@ -1516,7 +1516,7 @@ mjs_activatePlugin
.. mujoco-include:: mjs_activatePlugin .. mujoco-include:: mjs_activatePlugin
Activate plugin, return slot number. Activate plugin.
.. _Errorandmemory: .. _Errorandmemory:
+2 -3
View File
@@ -1739,9 +1739,8 @@ typedef struct mjsOrientation_ { // alternative orientation specifiers
} mjsOrientation; } mjsOrientation;
typedef struct mjsPlugin_ { // plugin specification typedef struct mjsPlugin_ { // plugin specification
mjsElement* element; // element type mjsElement* element; // element type
mjString* name; // name mjString* name; // instance name
mjString* plugin_name; // plugin name mjString* plugin_name; // plugin name
int plugin_slot; // global registered slot number of the plugin
mjtByte active; // is the plugin active mjtByte active; // is the plugin active
mjString* info; // message appended to compiler errors mjString* info; // message appended to compiler errors
} mjsPlugin; } mjsPlugin;
@@ -3171,7 +3170,7 @@ int mj_setLengthRange(mjModel* m, mjData* d, int index,
mjSpec* mj_makeSpec(void); mjSpec* mj_makeSpec(void);
mjSpec* mj_copySpec(const mjSpec* s); mjSpec* mj_copySpec(const mjSpec* s);
void mj_deleteSpec(mjSpec* s); void mj_deleteSpec(mjSpec* s);
int mjs_activatePlugin(mjSpec* s, const char* name); void mjs_activatePlugin(mjSpec* s, const char* name);
void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format); void mj_printFormattedModel(const mjModel* m, const char* filename, const char* float_format);
void mj_printModel(const mjModel* m, const char* filename); void mj_printModel(const mjModel* m, const char* filename);
void mj_printFormattedData(const mjModel* m, mjData* d, const char* filename, void mj_printFormattedData(const mjModel* m, mjData* d, const char* filename,
+1 -2
View File
@@ -182,9 +182,8 @@ typedef struct mjsOrientation_ { // alternative orientation specifiers
typedef struct mjsPlugin_ { // plugin specification typedef struct mjsPlugin_ { // plugin specification
mjsElement* element; // element type mjsElement* element; // element type
mjString* name; // name mjString* name; // instance name
mjString* plugin_name; // plugin name mjString* plugin_name; // plugin name
int plugin_slot; // global registered slot number of the plugin
mjtByte active; // is the plugin active mjtByte active; // is the plugin active
mjString* info; // message appended to compiler errors mjString* info; // message appended to compiler errors
} mjsPlugin; } mjsPlugin;
+2 -2
View File
@@ -241,8 +241,8 @@ MJAPI mjSpec* mj_copySpec(const mjSpec* s);
// Free memory allocation in mjSpec. // Free memory allocation in mjSpec.
MJAPI void mj_deleteSpec(mjSpec* s); MJAPI void mj_deleteSpec(mjSpec* s);
// Activate plugin, return slot number. // Activate plugin.
MJAPI int mjs_activatePlugin(mjSpec* s, const char* name); MJAPI void mjs_activatePlugin(mjSpec* s, const char* name);
//---------------------------------- Printing ------------------------------------------------------ //---------------------------------- Printing ------------------------------------------------------
+2 -2
View File
@@ -1048,7 +1048,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
('mjs_activatePlugin', ('mjs_activatePlugin',
FunctionDecl( FunctionDecl(
name='mjs_activatePlugin', name='mjs_activatePlugin',
return_type=ValueType(name='int'), return_type=ValueType(name='void'),
parameters=( parameters=(
FunctionParameterDecl( FunctionParameterDecl(
name='s', name='s',
@@ -1063,7 +1063,7 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
), ),
), ),
), ),
doc='Activate plugin, return slot number.', doc='Activate plugin.',
)), )),
('mj_printFormattedModel', ('mj_printFormattedModel',
FunctionDecl( FunctionDecl(
+1 -6
View File
@@ -8576,7 +8576,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([
type=PointerType( type=PointerType(
inner_type=ValueType(name='mjString'), inner_type=ValueType(name='mjString'),
), ),
doc='name', doc='instance name',
), ),
StructFieldDecl( StructFieldDecl(
name='plugin_name', name='plugin_name',
@@ -8585,11 +8585,6 @@ STRUCTS: Mapping[str, StructDecl] = dict([
), ),
doc='plugin name', doc='plugin name',
), ),
StructFieldDecl(
name='plugin_slot',
type=ValueType(name='int'),
doc='global registered slot number of the plugin',
),
StructFieldDecl( StructFieldDecl(
name='active', name='active',
type=ValueType(name='mjtByte'), type=ValueType(name='mjtByte'),
@@ -461,11 +461,6 @@ def generate_add() -> None:
} catch (const py::cast_error &e) { } catch (const py::cast_error &e) {
throw pybind11::value_error("plugin.instance_name should be a string."); throw pybind11::value_error("plugin.instance_name should be a string.");
} }
try {
plugin.plugin_slot = input->plugin_slot;
} catch (const py::cast_error &e) {
throw pybind11::value_error("plugin.plugin_slot should be an int.");
}
try { try {
plugin.active = input->active; plugin.active = input->active;
} catch (const py::cast_error &e) { } catch (const py::cast_error &e) {
-3
View File
@@ -207,13 +207,11 @@ class SpecsTest(absltest.TestCase):
plugin = spec.add_plugin( plugin = spec.add_plugin(
name='instance_name', name='instance_name',
plugin_name='mujoco.plugin', plugin_name='mujoco.plugin',
plugin_slot=7,
active=True, active=True,
info='info', info='info',
) )
self.assertEqual(plugin.name, 'instance_name') self.assertEqual(plugin.name, 'instance_name')
self.assertEqual(plugin.plugin_name, 'mujoco.plugin') self.assertEqual(plugin.plugin_name, 'mujoco.plugin')
self.assertEqual(plugin.plugin_slot, 7)
self.assertEqual(plugin.active, True) self.assertEqual(plugin.active, True)
self.assertEqual(plugin.info, 'info') self.assertEqual(plugin.info, 'info')
@@ -229,7 +227,6 @@ class SpecsTest(absltest.TestCase):
body_with_plugin = spec.worldbody.add_body(plugin=plugin) body_with_plugin = spec.worldbody.add_body(plugin=plugin)
self.assertEqual(body_with_plugin.plugin.name, 'instance_name') self.assertEqual(body_with_plugin.plugin.name, 'instance_name')
self.assertEqual(body_with_plugin.plugin.plugin_name, 'mujoco.plugin') self.assertEqual(body_with_plugin.plugin.plugin_name, 'mujoco.plugin')
self.assertEqual(body_with_plugin.plugin.plugin_slot, 7)
self.assertEqual(body_with_plugin.plugin.active, True) self.assertEqual(body_with_plugin.plugin.active, True)
self.assertEqual(body_with_plugin.plugin.info, 'info') self.assertEqual(body_with_plugin.plugin.info, 'info')
+1 -3
View File
@@ -206,16 +206,14 @@ void mjs_addSpec(mjSpec* s, mjSpec* child) {
// activate plugin // activate plugin
int mjs_activatePlugin(mjSpec* s, const char* name) { void mjs_activatePlugin(mjSpec* s, const char* name) {
int plugin_slot = -1; int plugin_slot = -1;
const mjpPlugin* plugin = mjp_getPlugin(name, &plugin_slot); const mjpPlugin* plugin = mjp_getPlugin(name, &plugin_slot);
if (!plugin) { if (!plugin) {
mju_error("unknown plugin '%s'", name); mju_error("unknown plugin '%s'", name);
return -1;
} }
mjCModel* model = static_cast<mjCModel*>(s->element); mjCModel* model = static_cast<mjCModel*>(s->element);
model->ActivatePlugin(plugin, plugin_slot); model->ActivatePlugin(plugin, plugin_slot);
return plugin_slot;
} }
+2 -2
View File
@@ -63,8 +63,8 @@ MJAPI void mj_deleteSpec(mjSpec* s);
// Add spec (model asset) to spec. // Add spec (model asset) to spec.
MJAPI void mjs_addSpec(mjSpec* s, mjSpec* child); MJAPI void mjs_addSpec(mjSpec* s, mjSpec* child);
// Activate plugin, return slot number. // Activate plugin.
MJAPI int mjs_activatePlugin(mjSpec* s, const char* name); MJAPI void mjs_activatePlugin(mjSpec* s, const char* name);
//---------------------------------- Attachment ---------------------------------------------------- //---------------------------------- Attachment ----------------------------------------------------
-1
View File
@@ -402,6 +402,5 @@ void mjs_defaultKey(mjsKey* key) {
// default plugin attributes // default plugin attributes
void mjs_defaultPlugin(mjsPlugin* plugin) { void mjs_defaultPlugin(mjsPlugin* plugin) {
memset(plugin, 0, sizeof(mjsPlugin)); memset(plugin, 0, sizeof(mjsPlugin));
plugin->plugin_slot = -1;
} }
+1 -1
View File
@@ -294,7 +294,7 @@ void mjCMesh::LoadSDF() {
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element); mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
plugin.element = plugin_instance; plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) { if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
throw mjCError(this, "plugin '%s' does not support signed distance fields", pplugin->name); throw mjCError(this, "plugin '%s' does not support signed distance fields", pplugin->name);
} }
+23 -8
View File
@@ -315,6 +315,7 @@ void mjCModel::CopyPlugin(std::vector<mjCPlugin*>& dest,
continue; continue;
} }
mjCPlugin* candidate = new mjCPlugin(*plugin); mjCPlugin* candidate = new mjCPlugin(*plugin);
candidate->model = this;
candidate->NameSpace(plugin->model); candidate->NameSpace(plugin->model);
bool referenced = instances.find(candidate->name) != instances.end(); bool referenced = instances.find(candidate->name) != instances.end();
auto same_name = [candidate](const mjCPlugin* dest) { return dest->name == candidate->name; }; auto same_name = [candidate](const mjCPlugin* dest) { return dest->name == candidate->name; };
@@ -3973,7 +3974,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) {
{ {
int adr = 0; int adr = 0;
for (int i = 0; i < nplugin; ++i) { for (int i = 0; i < nplugin; ++i) {
m->plugin[i] = plugins_[i]->spec.plugin_slot; m->plugin[i] = plugins_[i]->plugin_slot;
const int size = plugins_[i]->flattened_attributes.size(); const int size = plugins_[i]->flattened_attributes.size();
std::memcpy(m->plugin_attr + adr, std::memcpy(m->plugin_attr + adr,
plugins_[i]->flattened_attributes.data(), size); plugins_[i]->flattened_attributes.data(), size);
@@ -4499,24 +4500,37 @@ void mjCModel::ActivatePlugin(const mjpPlugin* plugin, int slot) {
void mjCModel::ResolvePlugin(mjCBase* obj, const std::string& plugin_name, void mjCModel::ResolvePlugin(mjCBase* obj, const std::string& plugin_name,
const std::string& plugin_instance_name, mjCPlugin** plugin_instance) { const std::string& plugin_instance_name, mjCPlugin** plugin_instance) {
std::string pname = plugin_name;
// if the plugin name is not specified by the user, infer it from the plugin instance
if (plugin_name.empty() && !plugin_instance_name.empty()) {
mjCBase* plugin_obj = FindObject(mjOBJ_PLUGIN, plugin_instance_name);
if (plugin_obj) {
pname = static_cast<mjCPlugin*>(plugin_obj)->plugin_name;
} else {
throw mjCError(obj, "unrecognized name '%s' for plugin instance",
plugin_instance_name.c_str());
}
}
// if plugin_name is specified, check if it is in the list of active plugins // if plugin_name is specified, check if it is in the list of active plugins
// (in XML, active plugins are those declared as <required>) // (in XML, active plugins are those declared as <required>)
int plugin_slot = -1; int plugin_slot = -1;
if (!plugin_name.empty()) { if (!pname.empty()) {
for (int i = 0; i < active_plugins_.size(); ++i) { for (int i = 0; i < active_plugins_.size(); ++i) {
if (active_plugins_[i].first->name == plugin_name) { if (active_plugins_[i].first->name == pname) {
plugin_slot = active_plugins_[i].second; plugin_slot = active_plugins_[i].second;
break; break;
} }
} }
if (plugin_slot == -1) { if (plugin_slot == -1) {
throw mjCError(obj, "unrecognized plugin '%s'", plugin_name.c_str()); throw mjCError(obj, "unrecognized plugin '%s'", pname.c_str());
} }
} }
// implicit plugin instance // implicit plugin instance
if (*plugin_instance && (*plugin_instance)->spec.plugin_slot == -1) { if (*plugin_instance && (*plugin_instance)->plugin_slot == -1) {
(*plugin_instance)->spec.plugin_slot = plugin_slot; (*plugin_instance)->plugin_slot = plugin_slot;
(*plugin_instance)->parent = obj; (*plugin_instance)->parent = obj;
} }
@@ -4524,14 +4538,15 @@ void mjCModel::ResolvePlugin(mjCBase* obj, const std::string& plugin_name,
else if (!*plugin_instance) { else if (!*plugin_instance) {
*plugin_instance = *plugin_instance =
static_cast<mjCPlugin*>(FindObject(mjOBJ_PLUGIN, plugin_instance_name)); static_cast<mjCPlugin*>(FindObject(mjOBJ_PLUGIN, plugin_instance_name));
(*plugin_instance)->plugin_slot = plugin_slot;
if (!*plugin_instance) { if (!*plugin_instance) {
throw mjCError( throw mjCError(
obj, "unrecognized name '%s' for plugin instance", plugin_instance_name.c_str()); obj, "unrecognized name '%s' for plugin instance", plugin_instance_name.c_str());
} }
if (plugin_slot != -1 && plugin_slot != (*plugin_instance)->spec.plugin_slot) { if (plugin_slot != -1 && plugin_slot != (*plugin_instance)->plugin_slot) {
throw mjCError( throw mjCError(
obj, "'plugin' attribute does not match that of the instance"); obj, "'plugin' attribute does not match that of the instance");
} }
plugin_slot = (*plugin_instance)->spec.plugin_slot; plugin_slot = (*plugin_instance)->plugin_slot;
} }
} }
+9 -5
View File
@@ -1695,7 +1695,7 @@ void mjCBody::Compile(void) {
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element); mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
plugin.element = plugin_instance; plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_PASSIVE)) { if (!(pplugin->capabilityflags & mjPLUGIN_PASSIVE)) {
throw mjCError(this, "plugin '%s' does not support passive forces", pplugin->name); throw mjCError(this, "plugin '%s' does not support passive forces", pplugin->name);
} }
@@ -2949,7 +2949,7 @@ void mjCGeom::Compile(void) {
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element); mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
plugin.element = plugin_instance; plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) { if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) {
throw mjCError(this, "plugin '%s' does not support sign distance fields", pplugin->name); throw mjCError(this, "plugin '%s' does not support sign distance fields", pplugin->name);
} }
@@ -5908,7 +5908,7 @@ void mjCActuator::Compile(void) {
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element); mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
plugin.element = plugin_instance; plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_ACTUATOR)) { if (!(pplugin->capabilityflags & mjPLUGIN_ACTUATOR)) {
throw mjCError(this, "plugin '%s' does not support actuators", pplugin->name); throw mjCError(this, "plugin '%s' does not support actuators", pplugin->name);
} }
@@ -6415,7 +6415,7 @@ void mjCSensor::Compile(void) {
mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element); mjCPlugin* plugin_instance = static_cast<mjCPlugin*>(plugin.element);
model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance);
plugin.element = plugin_instance; plugin.element = plugin_instance;
const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->plugin_slot);
if (!(pplugin->capabilityflags & mjPLUGIN_SENSOR)) { if (!(pplugin->capabilityflags & mjPLUGIN_SENSOR)) {
throw mjCError(this, "plugin '%s' does not support sensors", pplugin->name); throw mjCError(this, "plugin '%s' does not support sensors", pplugin->name);
} }
@@ -6918,6 +6918,7 @@ void mjCKey::Compile(const mjModel* m) {
mjCPlugin::mjCPlugin(mjCModel* _model) { mjCPlugin::mjCPlugin(mjCModel* _model) {
name = ""; name = "";
nstate = -1; nstate = -1;
plugin_slot = -1;
parent = this; parent = this;
model = _model; model = _model;
name.clear(); name.clear();
@@ -6945,6 +6946,7 @@ mjCPlugin& mjCPlugin::operator=(const mjCPlugin& other) {
this->spec = other.spec; this->spec = other.spec;
*static_cast<mjCPlugin_*>(this) = static_cast<const mjCPlugin_&>(other); *static_cast<mjCPlugin_*>(this) = static_cast<const mjCPlugin_&>(other);
parent = this; parent = this;
plugin_slot = other.plugin_slot;
} }
return *this; return *this;
} }
@@ -6953,7 +6955,9 @@ mjCPlugin& mjCPlugin::operator=(const mjCPlugin& other) {
// compiler // compiler
void mjCPlugin::Compile(void) { void mjCPlugin::Compile(void) {
const mjpPlugin* plugin = mjp_getPluginAtSlot(spec.plugin_slot); mjCPlugin* plugin_instance = this;
model->ResolvePlugin(this, plugin_name, name, &plugin_instance);
const mjpPlugin* plugin = mjp_getPluginAtSlot(plugin_slot);
// clear precompiled // clear precompiled
flattened_attributes.clear(); flattened_attributes.clear();
+2 -1
View File
@@ -1424,7 +1424,8 @@ class mjCPlugin : public mjCPlugin_ {
mjCPlugin(const mjCPlugin& other); mjCPlugin(const mjCPlugin& other);
mjCPlugin& operator=(const mjCPlugin& other); mjCPlugin& operator=(const mjCPlugin& other);
mjsPlugin spec; mjsPlugin spec;
mjCBase* parent; // parent object (only used when generating error message) mjCBase* parent; // parent object (only used when generating error message)
int plugin_slot; // global registered slot number of the plugin
private: private:
void Compile(void); // compiler void Compile(void); // compiler
+1 -2
View File
@@ -2890,7 +2890,7 @@ void mjXReader::Extension(XMLElement* section) {
if (name == "plugin") { if (name == "plugin") {
string plugin_name; string plugin_name;
ReadAttrTxt(elem, "plugin", plugin_name, /* required = */ true); ReadAttrTxt(elem, "plugin", plugin_name, /* required = */ true);
int plugin_slot = mjs_activatePlugin(spec, plugin_name.c_str()); mjs_activatePlugin(spec, plugin_name.c_str());
XMLElement* child = FirstChildElement(elem); XMLElement* child = FirstChildElement(elem);
while (child) { while (child) {
@@ -2909,7 +2909,6 @@ void mjXReader::Extension(XMLElement* section) {
throw mjXError(child, "plugin instance must have a name"); throw mjXError(child, "plugin instance must have a name");
} }
ReadPluginConfigs(child, p); ReadPluginConfigs(child, p);
p->plugin_slot = plugin_slot;
} }
child = NextSiblingElement(child); child = NextSiblingElement(child);
} }
+2 -2
View File
@@ -827,7 +827,7 @@ void mjXWriter::OnePlugin(XMLElement* elem, const mjsPlugin* plugin) {
} else { } else {
WriteAttrTxt(elem, "plugin", plugin_name); WriteAttrTxt(elem, "plugin", plugin_name);
const mjpPlugin* pplugin = mjp_getPluginAtSlot( const mjpPlugin* pplugin = mjp_getPluginAtSlot(
static_cast<mjCPlugin*>(plugin->element)->spec.plugin_slot); static_cast<mjCPlugin*>(plugin->element)->plugin_slot);
const char* c = &(static_cast<mjCPlugin*>(plugin->element)->flattened_attributes[0]); const char* c = &(static_cast<mjCPlugin*>(plugin->element)->flattened_attributes[0]);
for (int i = 0; i < pplugin->nattribute; ++i) { for (int i = 0; i < pplugin->nattribute; ++i) {
string value(c); string value(c);
@@ -1338,7 +1338,7 @@ void mjXWriter::Extension(XMLElement* root) {
} }
// check if we need to open a new <plugin> section // check if we need to open a new <plugin> section
const mjpPlugin* plugin = mjp_getPluginAtSlot(pp->spec.plugin_slot); const mjpPlugin* plugin = mjp_getPluginAtSlot(pp->plugin_slot);
if (plugin != last_plugin) { if (plugin != last_plugin) {
plugin_elem = InsertEnd(section, "plugin"); plugin_elem = InsertEnd(section, "plugin");
WriteAttrTxt(plugin_elem, "plugin", plugin->name); WriteAttrTxt(plugin_elem, "plugin", plugin->name);