Refactor VFS logic out of ResourceProvider plugin code.

PiperOrigin-RevId: 561302536
Change-Id: I952f9e76e85a7e3a111e0338f307378a6ff58197
This commit is contained in:
Kyle Bayes
2023-08-30 04:46:32 -07:00
committed by Copybara-Service
parent 215433f5f7
commit f86e8b449f
22 changed files with 310 additions and 445 deletions
+13 -11
View File
@@ -22,9 +22,11 @@
#include <string>
#include <mujoco/mjmodel.h>
#include "cc/array_safety.h"
#include "engine/engine_crossplatform.h"
#include "engine/engine_resource.h"
#include "engine/engine_vfs.h"
#include "user/user_model.h"
#include "user/user_util.h"
#include "xml/xml_native_reader.h"
@@ -110,7 +112,7 @@ string mjWriteXML(mjCModel* model, char* error, int error_sz) {
// find include elements recursively, replace them with subtree from xml file
static XMLElement* mjIncludeXML(XMLElement* elem, string dir,
int vfs_provider, vector<string>& included) {
const mjVFS* vfs, vector<string>& included) {
// include element: process
if (!strcasecmp(elem->Value(), "include")) {
// make sure include has no children
@@ -133,9 +135,9 @@ static XMLElement* mjIncludeXML(XMLElement* elem, string dir,
// get data source
mjResource *resource = nullptr;
const char* xmlstring = nullptr;
if ((resource = mju_openResource(filename.c_str(), vfs_provider)) == nullptr) {
// load from OS filesystem
if (!vfs_provider || (resource = mju_openResource(filename.c_str(), 0)) == nullptr) {
if ((resource = mju_openVfsResource(filename.c_str(), vfs)) == nullptr) {
// load from provider or OS filesystem
if ((resource = mju_openResource(filename.c_str())) == nullptr) {
throw mjXError(elem, "Could not open file '%s'", filename.c_str());
}
}
@@ -196,14 +198,14 @@ static XMLElement* mjIncludeXML(XMLElement* elem, string dir,
}
// run XMLInclude on first new child
return mjIncludeXML(first->ToElement(), dir, vfs_provider, included);
return mjIncludeXML(first->ToElement(), dir, vfs, included);
}
// otherwise check all child elements, return self
else {
XMLElement* child = elem->FirstChildElement();
while (child) {
child = mjIncludeXML(child, dir, vfs_provider, included);
child = mjIncludeXML(child, dir, vfs, included);
if (child) {
child = child->NextSiblingElement();
}
@@ -215,7 +217,7 @@ static XMLElement* mjIncludeXML(XMLElement* elem, string dir,
// Main parser function
mjCModel* mjParseXML(const char* filename, int vfs_provider, char* error, int error_sz) {
mjCModel* mjParseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz) {
LocaleOverride locale_override;
// check arguments
@@ -235,9 +237,9 @@ mjCModel* mjParseXML(const char* filename, int vfs_provider, char* error, int er
// get data source
mjResource* resource = nullptr;
const char* xmlstring = nullptr;
if ((resource = mju_openResource(filename, vfs_provider)) == nullptr) {
// load from OS filesystem
if (!vfs_provider || (resource = mju_openResource(filename, 0)) == nullptr) {
if ((resource = mju_openVfsResource(filename, vfs)) == nullptr) {
// load from provider or fallback to OS filesystem
if ((resource = mju_openResource(filename)) == nullptr) {
if (error) {
snprintf(error, error_sz, "mjParseXML: could not open file '%s'", filename);
}
@@ -303,7 +305,7 @@ mjCModel* mjParseXML(const char* filename, int vfs_provider, char* error, int er
// find include elements, replace them with subtree from xml file
vector<string> included;
included.push_back(filename);
mjIncludeXML(root, model->modelfiledir, vfs_provider, included);
mjIncludeXML(root, model->modelfiledir, vfs, included);
// parse MuJoCo model
mjXReader parser;
+1 -1
View File
@@ -26,7 +26,7 @@
std::string mjWriteXML(mjCModel* model, char* error, int error_sz);
// Main parser function
mjCModel* mjParseXML(const char* filename, int vfs_provider, char* error, int error_sz);
mjCModel* mjParseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz);
#endif // MUJOCO_SRC_XML_XML_H_
+8 -30
View File
@@ -70,20 +70,23 @@ static std::mutex themutex;
//---------------------------------- Functions -----------------------------------------------------
// mj_loadXML helper function
mjModel* _loadXML(const char* filename, int vfs_provider,
char* error, int error_sz) {
// parse XML file in MJCF or URDF format, compile it, return low-level model
// if vfs is not NULL, look up files in vfs before reading from disk
// error can be NULL; otherwise assumed to have size error_sz
mjModel* mj_loadXML(const char* filename, const mjVFS* vfs,
char* error, int error_sz) {
// serialize access to themodel
std::lock_guard<std::mutex> lock(themutex);
// parse new model
mjCModel* newmodel = mjParseXML(filename, vfs_provider, error, error_sz);
mjCModel* newmodel = mjParseXML(filename, vfs, error, error_sz);
if (!newmodel) {
return nullptr;
}
// compile new model
mjModel* m = newmodel->Compile(vfs_provider);
mjModel* m = newmodel->Compile(vfs);
if (!m) {
mjCopyError(error, newmodel->GetError().message, error_sz);
delete newmodel;
@@ -106,31 +109,6 @@ mjModel* _loadXML(const char* filename, int vfs_provider,
// parse XML file in MJCF or URDF format, compile it, return low-level model
// if vfs is not NULL, look up files in vfs before reading from disk
// error can be NULL; otherwise assumed to have size error_sz
mjModel* mj_loadXML(const char* filename, const mjVFS* vfs,
char* error, int error_sz) {
if (vfs == nullptr) {
return _loadXML(filename, 0, error, error_sz);
}
int index = mj_registerVfsProvider(vfs);
if (index < 1) {
if (error) {
snprintf(error, error_sz, "mj_loadXML: could not register VFS");
}
return nullptr;
}
mjModel* model = _loadXML(filename, index, error, error_sz);
mjp_unregisterResourceProvider(index);
return model;
}
// update XML data structures with info from low-level model, save as MJCF
// returns 1 if successful, 0 otherwise
// error can be NULL; otherwise assumed to have size error_sz