Add various improvements for resource providers.
PiperOrigin-RevId: 529706437 Change-Id: I20385e031446674584349c301982dbe13b812477
This commit is contained in:
committed by
Copybara-Service
parent
b798f89212
commit
67f0f5154f
+22
-14
@@ -129,7 +129,7 @@ bool mjWriteXML(mjCModel* model, string filename, char* error, int error_sz) {
|
||||
|
||||
// find include elements recursively, replace them with subtree from xml file
|
||||
static XMLElement* mjIncludeXML(XMLElement* elem, string dir,
|
||||
int default_provider, vector<string>& included) {
|
||||
int vfs_provider, vector<string>& included) {
|
||||
// include element: process
|
||||
if (!strcasecmp(elem->Value(), "include")) {
|
||||
// make sure include has no children
|
||||
@@ -152,9 +152,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(), default_provider)) == nullptr) {
|
||||
if ((resource = mju_openResource(filename.c_str(), vfs_provider)) == nullptr) {
|
||||
// load from OS filesystem
|
||||
if (!default_provider || (resource = mju_openResource(filename.c_str(), 0)) == nullptr) {
|
||||
if (!vfs_provider || (resource = mju_openResource(filename.c_str(), 0)) == nullptr) {
|
||||
throw mjXError(elem, "Could not open file '%s'", filename.c_str());
|
||||
}
|
||||
}
|
||||
@@ -215,14 +215,14 @@ static XMLElement* mjIncludeXML(XMLElement* elem, string dir,
|
||||
}
|
||||
|
||||
// run XMLInclude on first new child
|
||||
return mjIncludeXML(first->ToElement(), dir, default_provider, included);
|
||||
return mjIncludeXML(first->ToElement(), dir, vfs_provider, included);
|
||||
}
|
||||
|
||||
// otherwise check all child elements, return self
|
||||
else {
|
||||
XMLElement* child = elem->FirstChildElement();
|
||||
while (child) {
|
||||
child = mjIncludeXML(child, dir, default_provider, included);
|
||||
child = mjIncludeXML(child, dir, vfs_provider, included);
|
||||
if (child) {
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
@@ -234,7 +234,7 @@ static XMLElement* mjIncludeXML(XMLElement* elem, string dir,
|
||||
|
||||
|
||||
// Main parser function
|
||||
mjCModel* mjParseXML(const char* filename, int default_provider, char* error, int error_sz) {
|
||||
mjCModel* mjParseXML(const char* filename, int vfs_provider, char* error, int error_sz) {
|
||||
LocaleOverride locale_override;
|
||||
|
||||
// check arguments
|
||||
@@ -254,9 +254,9 @@ mjCModel* mjParseXML(const char* filename, int default_provider, char* error, in
|
||||
// get data source
|
||||
mjResource* resource = nullptr;
|
||||
const char* xmlstring = nullptr;
|
||||
if ((resource = mju_openResource(filename, default_provider)) == nullptr) {
|
||||
if ((resource = mju_openResource(filename, vfs_provider)) == nullptr) {
|
||||
// load from OS filesystem
|
||||
if (!default_provider || (resource = mju_openResource(filename, 0)) == nullptr) {
|
||||
if (!vfs_provider || (resource = mju_openResource(filename, 0)) == nullptr) {
|
||||
if (error) {
|
||||
snprintf(error, error_sz, "mjParseXML: could not open file '%s'", filename);
|
||||
}
|
||||
@@ -284,29 +284,37 @@ mjCModel* mjParseXML(const char* filename, int default_provider, char* error, in
|
||||
XMLDocument doc;
|
||||
doc.Parse(xmlstring, buffer_size);
|
||||
|
||||
// close resource
|
||||
mju_closeResource(resource);
|
||||
|
||||
|
||||
// error checking
|
||||
if (doc.Error()) {
|
||||
if (error) {
|
||||
snprintf(error, error_sz, "XML parse error %d:\n%s\n",
|
||||
doc.ErrorID(), doc.ErrorStr());
|
||||
}
|
||||
mju_closeResource(resource);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// get top-level element
|
||||
XMLElement* root = doc.RootElement();
|
||||
if (!root) {
|
||||
mju_closeResource(resource);
|
||||
mjCopyError(error, "XML root element not found", error_sz);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// create model, set filedir
|
||||
model = new mjCModel;
|
||||
model->modelfiledir = mjuu_getfiledir(filename);
|
||||
const char* dir;
|
||||
int ndir = 0;
|
||||
mju_getResourceDir(resource, &dir, &ndir);
|
||||
if (dir != nullptr) {
|
||||
model->modelfiledir = std::string(dir, ndir);
|
||||
} else {
|
||||
model->modelfiledir = "";
|
||||
}
|
||||
|
||||
// close resource
|
||||
mju_closeResource(resource);
|
||||
|
||||
// parse with exceptions
|
||||
try {
|
||||
@@ -314,7 +322,7 @@ mjCModel* mjParseXML(const char* filename, int default_provider, char* error, in
|
||||
// find include elements, replace them with subtree from xml file
|
||||
vector<string> included;
|
||||
included.push_back(filename);
|
||||
mjIncludeXML(root, model->modelfiledir, default_provider, included);
|
||||
mjIncludeXML(root, model->modelfiledir, vfs_provider, included);
|
||||
|
||||
// parse MuJoCo model
|
||||
mjXReader parser;
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@
|
||||
bool mjWriteXML(mjCModel* model, std::string filename, char* error, int error_sz);
|
||||
|
||||
// Main parser function
|
||||
mjCModel* mjParseXML(const char* filename, int default_provider, char* error, int error_sz);
|
||||
mjCModel* mjParseXML(const char* filename, int vfs_provider, char* error, int error_sz);
|
||||
|
||||
|
||||
#endif // MUJOCO_SRC_XML_XML_H_
|
||||
|
||||
+3
-3
@@ -83,19 +83,19 @@ void mj_deactivate(void) {
|
||||
|
||||
|
||||
// mj_loadXML helper function
|
||||
mjModel* _loadXML(const char* filename, int default_provider,
|
||||
mjModel* _loadXML(const char* filename, int vfs_provider,
|
||||
char* error, int error_sz) {
|
||||
// serialize access to themodel
|
||||
std::lock_guard<std::mutex> lock(themutex);
|
||||
|
||||
// parse new model
|
||||
mjCModel* newmodel = mjParseXML(filename, default_provider, error, error_sz);
|
||||
mjCModel* newmodel = mjParseXML(filename, vfs_provider, error, error_sz);
|
||||
if (!newmodel) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// compile new model
|
||||
mjModel* m = newmodel->Compile(default_provider);
|
||||
mjModel* m = newmodel->Compile(vfs_provider);
|
||||
if (!m) {
|
||||
mjCopyError(error, newmodel->GetError().message, error_sz);
|
||||
delete newmodel;
|
||||
|
||||
Reference in New Issue
Block a user