Fix a bug with mjs_delete functions.

PiperOrigin-RevId: 657615906
Change-Id: Ic70eaa9a5c20337db3897cf882a60e9d94f2869b
This commit is contained in:
Alessio Quaglino
2024-07-30 09:12:57 -07:00
committed by Copybara-Service
parent 24a555062d
commit b341bd391d
5 changed files with 119 additions and 3 deletions
+2 -2
View File
@@ -148,7 +148,7 @@ int mjs_detachBody(mjSpec* s, mjsBody* b) {
mjCModel* model = static_cast<mjCModel*>(s->element);
mjCBody* body = static_cast<mjCBody*>(b->element);
*model -= *body;
mjs_delete(b->element);
delete body;
return 0;
}
@@ -181,7 +181,7 @@ void mjs_addSpec(mjSpec* s, mjSpec* child) {
// delete object, it will call the appropriate destructor since ~mjCBase is virtual
void mjs_delete(mjsElement* element) {
mjCBase* object = static_cast<mjCBase*>(element);
delete object;
object->model->DeleteElement(element);
}
+62
View File
@@ -340,6 +340,68 @@ mjCModel_& mjCModel::operator+=(mjCDef& subtree) {
template <class T>
void deletefromlist(std::vector<T*>* list, mjsElement* element) {
if (!list) {
return;
}
for (int j = 0; j < list->size(); ++j) {
list->at(j)->id = -1;
if (list->at(j) == element) {
delete list->at(j);
list->erase(list->begin() + j);
j--;
}
}
}
// discard all invalid elements from all lists
void mjCModel::DeleteElement(mjsElement* el) {
mjCBody *world = bodies_[0];
if (compiled) {
ResetTreeLists();
}
switch (el->elemtype) {
case mjOBJ_BODY:
throw mjCError(NULL, "bodies cannot be deleted, use detach instead");
break;
case mjOBJ_GEOM:
deletefromlist(&(static_cast<mjCGeom*>(el)->body->geoms), el);
break;
case mjOBJ_SITE:
deletefromlist(&(static_cast<mjCSite*>(el)->body->sites), el);
break;
case mjOBJ_JOINT:
deletefromlist(&(static_cast<mjCJoint*>(el)->body->joints), el);
break;
case mjOBJ_LIGHT:
deletefromlist(&(static_cast<mjCLight*>(el)->body->lights), el);
break;
case mjOBJ_CAMERA:
deletefromlist(&(static_cast<mjCCamera*>(el)->body->cameras), el);
break;
default:
deletefromlist(object_lists_[el->elemtype], el);
break;
}
if (compiled) {
MakeLists(world);
ProcessLists(/*checkrepeat=*/false);
}
}
// TODO: we should not use C-type casting with multiple C++ inheritance
void mjCModel::CreateObjectLists() {
for (int i = 0; i < mjNOBJECT; ++i) {
+3
View File
@@ -202,6 +202,9 @@ class mjCModel : public mjCModel_, private mjSpec {
// delete all elements
template <class T> void DeleteAll(std::vector<T*>& elements);
// delete object from the corresponding list
void DeleteElement(mjsElement* el);
// API for access to model elements (outside tree)
int NumObjects(mjtObj type); // number of objects in specified list
mjCBase* GetObject(mjtObj type, int id); // pointer to specified object