From 78dc5aee9fbb1102df9d8e1b234606ae7275e3db Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Tue, 20 Feb 2024 03:45:42 -0800 Subject: [PATCH] Remove mjCPlugin from xml_native_reader. PiperOrigin-RevId: 608546883 Change-Id: Ib529c2756102e4e2185d1d8e9585187c30049011 --- src/user/user_api.cc | 17 ++++++++++++++-- src/user/user_api.h | 7 ++++++- src/user/user_composite.cc | 6 ++++++ src/user/user_flexcomp.cc | 6 ++++++ src/user/user_init.cc | 1 + src/user/user_mesh.cc | 2 +- src/user/user_model.cc | 10 +++++----- src/user/user_objects.cc | 31 ++++++++++++----------------- src/user/user_objects.h | 23 ++++++++++++---------- src/xml/xml_native_reader.cc | 38 ++++++++++++------------------------ src/xml/xml_native_reader.h | 2 -- src/xml/xml_native_writer.cc | 28 +++++++++++++------------- src/xml/xml_native_writer.h | 2 +- 13 files changed, 93 insertions(+), 80 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index e666f63d..e54d402b 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -13,7 +13,10 @@ // limitations under the License. #include "user/user_api.h" +#include +#include #include +#include #include #include @@ -318,8 +321,8 @@ mjmKey* mjm_addKey(mjmModel* model) { mjmPlugin* mjm_addPlugin(mjmModel* model) { mjCModel* modelC = reinterpret_cast(model->element); mjCPlugin* plugin = modelC->AddPlugin(); - plugin->plugin.instance = (mjElement)plugin; - return &plugin->plugin; + plugin->spec.instance = (mjElement)plugin; + return &plugin->spec; } @@ -508,6 +511,16 @@ const double* mjm_getDouble(const mjDoubleVec source, int* size) { +// set plugin attributes +void mjm_setPluginAttributes(mjmPlugin* plugin, void* attributes) { + mjCPlugin* pluginC = reinterpret_cast(plugin->instance); + std::map>* config_attribs = + reinterpret_cast>*>(attributes); + pluginC->config_attribs = std::move(*config_attribs); +} + + + // compute full inertia const char* mjm_setFullInertia(mjmBody* bodyspec, double quat[4], double inertia[3]) { mjCBody* body = reinterpret_cast(bodyspec->element); diff --git a/src/user/user_api.h b/src/user/user_api.h index 9d9eee68..9d0f869f 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -88,7 +88,9 @@ typedef struct _mjmPlugin { // plugin specification mjElement instance; // internal, do not modify mjString name; // name mjString instance_name; // instance name - bool active; // is the plugin active + int plugin_slot; // global registered slot number of the plugin + mjtByte active; // is the plugin active + mjString info; // message appended to compiler errors } mjmPlugin; @@ -814,6 +816,9 @@ MJAPI const char* mjm_getString(mjString source); // Get double array contents and optionally its size. MJAPI const double* mjm_getDouble(mjDoubleVec source, int* size); +// Set plugin attributes. +MJAPI void mjm_setPluginAttributes(mjmPlugin* plugin, void* attributes); + // Set default. MJAPI void mjm_setDefault(mjElement element, mjmDefault* def); diff --git a/src/user/user_composite.cc b/src/user/user_composite.cc index 058d7b39..55ad7bef 100644 --- a/src/user/user_composite.cc +++ b/src/user/user_composite.cc @@ -308,6 +308,12 @@ bool mjCComposite::Make(mjCModel* model, mjmBody* body, char* error, int error_s } } + // overwrite plugin name + if (plugin_instance_name.empty() && plugin.active) { + plugin_instance_name = "composite" + prefix; + ((mjCPlugin*)plugin.instance)->name = plugin_instance_name; + } + // dispatch switch (type) { case mjCOMPTYPE_PARTICLE: diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 0a754073..4c880f58 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -397,6 +397,12 @@ bool mjCFlexcomp::Make(mjCModel* model, mjmBody* body, char* error, int error_sz double bodymass = mass/npnt; double bodyinertia = bodymass*(2.0*inertiabox*inertiabox)/3.0; + // overwrite plugin name + if (plugin.active && plugin_instance_name.empty()) { + plugin_instance_name = "flexcomp_" + name; + ((mjCPlugin*)plugin.instance)->name = plugin_instance_name; + } + // create bodies, construct flex vert and vertbody for (int i=0; iResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->plugin_slot); + 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); } diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 782d0a8f..b0b21831 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -3044,7 +3044,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { { int adr = 0; for (int i = 0; i < nplugin; ++i) { - m->plugin[i] = plugins[i]->plugin_slot; + m->plugin[i] = plugins[i]->spec.plugin_slot; const int size = plugins[i]->flattened_attributes.size(); std::memcpy(m->plugin_attr + adr, plugins[i]->flattened_attributes.data(), size); @@ -3575,8 +3575,8 @@ void mjCModel::ResolvePlugin(mjCBase* obj, const std::string& plugin_name, } // implicit plugin instance - if (*plugin_instance && (*plugin_instance)->plugin_slot == -1) { - (*plugin_instance)->plugin_slot = plugin_slot; + if (*plugin_instance && (*plugin_instance)->spec.plugin_slot == -1) { + (*plugin_instance)->spec.plugin_slot = plugin_slot; (*plugin_instance)->parent = obj; } @@ -3588,10 +3588,10 @@ void mjCModel::ResolvePlugin(mjCBase* obj, const std::string& plugin_name, throw mjCError( obj, "unrecognized name '%s' for plugin instance", plugin_instance_name.c_str()); } - if (plugin_slot != -1 && plugin_slot != (*plugin_instance)->plugin_slot) { + if (plugin_slot != -1 && plugin_slot != (*plugin_instance)->spec.plugin_slot) { throw mjCError( obj, "'plugin' attribute does not match that of the instance"); } - plugin_slot = (*plugin_instance)->plugin_slot; + plugin_slot = (*plugin_instance)->spec.plugin_slot; } } diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 0a36b708..6e55fcbe 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -544,13 +544,6 @@ mjCBase::mjCBase() { model = 0; def = 0; frame = nullptr; - - // plugin variables - mjm_defaultPlugin(plugin); - plugin_name = ""; - plugin_instance_name = ""; - plugin.name = (mjString)&plugin_name; - plugin.instance_name = (mjString)&plugin_instance_name; } @@ -1193,7 +1186,7 @@ void mjCBody::Compile(void) { mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->plugin_slot); + 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); } @@ -2047,7 +2040,7 @@ void mjCGeom::Compile(void) { mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->plugin_slot); + 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); } @@ -4487,7 +4480,7 @@ void mjCActuator::Compile(void) { mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->plugin_slot); + 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); } @@ -4921,7 +4914,7 @@ void mjCSensor::Compile(void) { { mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->plugin_slot); + 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); } @@ -5332,24 +5325,24 @@ void mjCKey::Compile(const mjModel* m) { // initialize defaults mjCPlugin::mjCPlugin(mjCModel* _model) { name = ""; - plugin_slot = -1; - nstate = 0; + nstate = -1; parent = this; model = _model; + name.clear(); + instance_name.clear(); // public interface - mjm_defaultPlugin(plugin); - plugin_name = ""; - plugin_instance_name = ""; - plugin.name = (mjString)&plugin_name; - plugin.instance_name = (mjString)&plugin_instance_name; + mjm_defaultPlugin(spec); + spec.name = (mjString)&name; + spec.instance_name = (mjString)&instance_name; + spec.info = (mjString)&info; } // compiler void mjCPlugin::Compile(void) { - const mjpPlugin* plugin = mjp_getPluginAtSlot(this->plugin_slot); + const mjpPlugin* plugin = mjp_getPluginAtSlot(spec.plugin_slot); // concatenate all of the plugin's attribute values (as null-terminated strings) into // flattened_attributes, in the order declared in the mjpPlugin diff --git a/src/user/user_objects.h b/src/user/user_objects.h index b843862e..2bafb703 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -173,10 +173,6 @@ class mjCBase { mjCModel* model; // pointer to model that created object mjCFrame* frame; // pointer to frame transformation - // plugin support - mjmPlugin plugin; - std::string plugin_name; - std::string plugin_instance_name; protected: mjCBase(); // constructor virtual ~mjCBase() = default; // destructor @@ -233,7 +229,6 @@ class mjCBody : public mjCBase, private mjmBody { using mjCBase::name; using mjCBase::classname; using mjCBase::info; - using mjCBase::plugin; // used by mjXWriter and mjCModel const std::vector& get_userdata() { return userdata_; } @@ -278,6 +273,8 @@ class mjCBody : public mjCBase, private mjmBody { void PointToLocal(void); // variable-size data + std::string plugin_name; + std::string plugin_instance_name; std::vector userdata_; std::vector spec_userdata_; }; @@ -415,6 +412,8 @@ class mjCGeom : public mjCBase, private mjmGeom { mjtNum fluid[mjNFLUID]; // compile-time fluid-interaction parameters // variable-size data + std::string plugin_name; + std::string plugin_instance_name; std::string hfieldname_; std::string meshname_; std::string material_; @@ -427,7 +426,6 @@ class mjCGeom : public mjCBase, private mjmGeom { // inherited using mjCBase::classname; using mjCBase::info; - using mjCBase::plugin; }; @@ -625,7 +623,6 @@ class mjCMesh: public mjCBase, private mjmMesh { mjmMesh spec; using mjCBase::name; using mjCBase::classname; - using mjCBase::plugin; using mjCBase::info; void CopyFromSpec(void); @@ -687,6 +684,9 @@ class mjCMesh: public mjCBase, private mjmMesh { private: // variable size attributes + std::string plugin_name; + std::string plugin_instance_name; + std::string content_type_; // content type of file std::string file_; // mesh file std::vector uservert_; // user vertex data @@ -1164,7 +1164,7 @@ class mjCPlugin : public mjCBase { friend class mjXWriter; public: - int plugin_slot; // global registered slot number of the plugin + mjmPlugin spec; int nstate; // state size for the plugin instance mjCBase* parent; // parent object (only used when generating error message) std::map> config_attribs; // raw config attributes from XML @@ -1173,6 +1173,7 @@ class mjCPlugin : public mjCBase { private: mjCPlugin(mjCModel*); // constructor void Compile(void); // compiler + std::string instance_name; }; @@ -1190,7 +1191,6 @@ class mjCActuator : public mjCBase, private mjmActuator { using mjCBase::name; using mjCBase::classname; using mjCBase::info; - using mjCBase::plugin; // used by mjXWriter and mjCModel const std::vector& get_userdata() { return userdata_; } @@ -1211,6 +1211,8 @@ class mjCActuator : public mjCBase, private mjmActuator { int trnid[2]; // id of transmission target // variable-size data + std::string plugin_name; + std::string plugin_instance_name; std::string target_; std::string slidersite_; std::string refsite_; @@ -1236,7 +1238,6 @@ class mjCSensor : public mjCBase, private mjmSensor { using mjCBase::name; using mjCBase::classname; using mjCBase::info; - using mjCBase::plugin; // used by mjXWriter and mjCModel const std::vector& get_userdata() { return userdata_; } @@ -1253,6 +1254,8 @@ class mjCSensor : public mjCBase, private mjmSensor { int refid; // id of reference frame // variable-size data + std::string plugin_name; + std::string plugin_instance_name; std::string objname_; std::string refname_; std::vector userdata_; diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 8c713cc1..9449878c 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -40,7 +40,6 @@ #include "user/user_composite.h" #include "user/user_flexcomp.h" #include "user/user_model.h" -#include "user/user_objects.h" #include "user/user_util.h" #include "xml/xml_base.h" #include "xml/xml_util.h" @@ -50,7 +49,7 @@ using std::string; using std::vector; using tinyxml2::XMLElement; -void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjCPlugin* pp) { +void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjmPlugin* p) { std::map> config_attribs; XMLElement* child = FirstChildElement(elem); while (child) { @@ -68,12 +67,12 @@ void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjCPlugin* pp) { child = NextSiblingElement(child); } - if (!pp && !config_attribs.empty()) { + if (!p && !config_attribs.empty()) { throw mjXError(elem, "plugin configuration attributes cannot be used in an " "element that references a predefined plugin instance"); - } else if (pp) { - pp->config_attribs = std::move(config_attribs); + } else if (p) { + mjm_setPluginAttributes(p, &config_attribs); } } } // namespace @@ -2276,10 +2275,6 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) XMLElement* eplugin = FirstChildElement(elem, "plugin"); if (eplugin) { OnePlugin(eplugin, &comp.plugin); - if (comp.plugin_instance_name.empty()) { - comp.plugin_instance_name = "composite" + comp.prefix; - ((mjCPlugin*)comp.plugin.instance)->name = comp.plugin_instance_name; - } } // cable @@ -2602,10 +2597,6 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjmBody* pbody) { XMLElement* eplugin = FirstChildElement(elem, "plugin"); if (eplugin) { OnePlugin(eplugin, &fcomp.plugin); - if (fcomp.plugin_instance_name.empty()) { - fcomp.plugin_instance_name = "flexcomp_" + fcomp.name; - ((mjCPlugin*)fcomp.plugin.instance)->name = fcomp.plugin_instance_name; - } } // make flexcomp @@ -2631,7 +2622,7 @@ void mjXReader::OnePlugin(XMLElement* elem, mjmPlugin* plugin) { mjm_setString(plugin->instance_name, instance_name.c_str()); if (instance_name.empty()) { plugin->instance = mjm_addPlugin(&model->spec)->instance; - ReadPluginConfigs(elem, (mjCPlugin*)plugin->instance); + ReadPluginConfigs(elem, plugin); } else { model->hasImplicitPluginElem = true; } @@ -2789,15 +2780,16 @@ void mjXReader::Extension(XMLElement* section) { throw mjXError( child, "explicit plugin instance must appear before implicit plugin elements"); } - mjCPlugin* pp = (mjCPlugin*)mjm_addPlugin(&model->spec)->instance; - GetXMLPos(child, pp); - ReadAttrTxt(child, "name", pp->name, /* required = */ true); - if (pp->name.empty()) { + string name; + mjmPlugin* p = mjm_addPlugin(&model->spec); + mjm_setString(p->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + ReadAttrTxt(child, "name", name, /* required = */ true); + mjm_setString(p->name, name.c_str()); + if (!p->name) { throw mjXError(child, "plugin instance must have a name"); } - ReadPluginConfigs(child, pp); - pp->plugin_slot = plugin_slot; - pp->nstate = -1; // actual value to be filled in by the plugin later + ReadPluginConfigs(child, p); + p->plugin_slot = plugin_slot; } child = NextSiblingElement(child); } @@ -4034,10 +4026,6 @@ mjmDefault* mjXReader::GetClass(XMLElement* section) { -// get xml position -void mjXReader::GetXMLPos(XMLElement* elem, mjCBase* obj) { - obj->info = "line = " + std::to_string(elem->GetLineNum()); -} // return true if c is a directory path separator (i.e. '/' or '\' on windows) static bool IsSeperator(char c) { diff --git a/src/xml/xml_native_reader.h b/src/xml/xml_native_reader.h index 3c225011..289a5370 100644 --- a/src/xml/xml_native_reader.h +++ b/src/xml/xml_native_reader.h @@ -23,7 +23,6 @@ #include #include "user/user_api.h" #include "user/user_model.h" -#include "user/user_objects.h" #include "xml/xml_base.h" #include "xml/xml_util.h" @@ -86,7 +85,6 @@ class mjXReader : public mjXBase { mjXSchema schema; // schema used for validation mjmDefault* GetClass(tinyxml2::XMLElement* section); // get default class name - static void GetXMLPos(tinyxml2::XMLElement* elem, mjCBase* obj); // get xml position bool readingdefaults; // true while reading defaults diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index 3eae2fe1..1aa48403 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -412,7 +412,7 @@ void mjXWriter::OneGeom(XMLElement* elem, mjCGeom* pgeom, mjCDef* def) { // write plugin if (pgeom->plugin.active) { - OnePlugin(InsertEnd(elem, "plugin"), pgeom); + OnePlugin(InsertEnd(elem, "plugin"), &pgeom->plugin); } } @@ -702,7 +702,7 @@ void mjXWriter::OneActuator(XMLElement* elem, mjCActuator* pact, mjCDef* def) { // plugins: write config attributes if (pact->plugin.active) { - OnePlugin(elem, pact); + OnePlugin(elem, &pact->plugin); } // non-plugins: write actuator parameters @@ -731,21 +731,21 @@ void mjXWriter::OneActuator(XMLElement* elem, mjCActuator* pact, mjCDef* def) { // write plugin -void mjXWriter::OnePlugin(XMLElement* elem, mjCBase* object) { - const std::string instance_name = std::string(mjm_getString(object->plugin.instance_name)); - const std::string plugin_name = std::string(mjm_getString(object->plugin.name)); +void mjXWriter::OnePlugin(XMLElement* elem, mjmPlugin* plugin) { + const std::string instance_name = std::string(mjm_getString(plugin->instance_name)); + const std::string plugin_name = std::string(mjm_getString(plugin->name)); if (!instance_name.empty()) { WriteAttrTxt(elem, "instance", instance_name); } else { WriteAttrTxt(elem, "plugin", plugin_name); - const mjpPlugin* plugin = mjp_getPluginAtSlot( - ((mjCPlugin*)object->plugin.instance)->plugin_slot); - const char* c = &((mjCPlugin*)object->plugin.instance)->flattened_attributes[0]; - for (int i = 0; i < plugin->nattribute; ++i) { + const mjpPlugin* pplugin = mjp_getPluginAtSlot( + ((mjCPlugin*)plugin->instance)->spec.plugin_slot); + const char* c = &((mjCPlugin*)plugin->instance)->flattened_attributes[0]; + for (int i = 0; i < pplugin->nattribute; ++i) { std::string value(c); if (!value.empty()) { XMLElement* config_elem = InsertEnd(elem, "config"); - WriteAttrTxt(config_elem, "key", plugin->attributes[i]); + WriteAttrTxt(config_elem, "key", pplugin->attributes[i]); WriteAttrTxt(config_elem, "value", value); c += value.size(); } @@ -1229,7 +1229,7 @@ void mjXWriter::Extension(XMLElement* root) { } // check if we need to open a new section - const mjpPlugin* plugin = mjp_getPluginAtSlot(pp->plugin_slot); + const mjpPlugin* plugin = mjp_getPluginAtSlot(pp->spec.plugin_slot); if (plugin != last_plugin) { plugin_elem = InsertEnd(section, "plugin"); WriteAttrTxt(plugin_elem, "plugin", plugin->name); @@ -1406,7 +1406,7 @@ void mjXWriter::Asset(XMLElement* root) { if (pmesh->plugin.active) { elem = InsertEnd(section, "mesh"); WriteAttrTxt(elem, "name", pmesh->name); - OnePlugin(InsertEnd(elem, "plugin"), pmesh); + OnePlugin(InsertEnd(elem, "plugin"), &pmesh->plugin); } else{ elem = InsertEnd(section, "mesh"); OneMesh(elem, pmesh, pmesh->def); @@ -1506,7 +1506,7 @@ void mjXWriter::Body(XMLElement* elem, mjCBody* body) { // write plugin if (body->plugin.active) { - OnePlugin(InsertEnd(elem, "plugin"), body); + OnePlugin(InsertEnd(elem, "plugin"), &body->plugin); } // write child bodies recursively @@ -1904,7 +1904,7 @@ void mjXWriter::Sensor(XMLElement* root) { WriteAttrTxt(elem, "objtype", mju_type2Str(psen->objtype)); WriteAttrTxt(elem, "objname", psen->get_objname()); } - OnePlugin(elem, psen); + OnePlugin(elem, &psen->plugin); break; // user-defined sensor diff --git a/src/xml/xml_native_writer.h b/src/xml/xml_native_writer.h index 53a67bf4..684a6e0a 100644 --- a/src/xml/xml_native_writer.h +++ b/src/xml/xml_native_writer.h @@ -66,7 +66,7 @@ class mjXWriter : public mjXBase { void OneEquality(tinyxml2::XMLElement* elem, mjCEquality* pequality, mjCDef* def); void OneTendon(tinyxml2::XMLElement* elem, mjCTendon* ptendon, mjCDef* def); void OneActuator(tinyxml2::XMLElement* elem, mjCActuator* pactuator, mjCDef* def); - void OnePlugin(tinyxml2::XMLElement* elem, mjCBase* object); + void OnePlugin(tinyxml2::XMLElement* elem, mjmPlugin* plugin); bool writingdefaults; // true during defaults write };