Add a new plugin / extension mechanism called a resource provider along with retrofitting VFS on top of it.

A resource provider provides a mechanism for MuJoCo to read from filesystems other than the OS filesystem or the Virtual File System (VFS).

PiperOrigin-RevId: 525394983
Change-Id: I077ff5a7e2e76806b48b6defb531280aadc8b169
This commit is contained in:
Kyle Bayes
2023-04-19 03:01:33 -07:00
committed by Copybara-Service
parent b25728cc2e
commit fe3dccfd1d
27 changed files with 1467 additions and 607 deletions
+55 -2
View File
@@ -18,7 +18,8 @@
#include <stdlib.h>
#include "engine/engine_array_safety.h"
#include "engine/engine_file.h"
#include "engine/engine_plugin.h"
#include "engine/engine_resource.h"
#include "engine/engine_util_errmem.h"
#include "engine/engine_util_misc.h"
@@ -154,7 +155,6 @@ int mj_findFileVFS(const mjVFS* vfs, const char* filename) {
// strip path
char newname[mjMAXVFSNAME];
vfs_strippath(newname, filename);
// find specific file
for (int i=0; i<vfs->nfile; i++) {
if (strncmp(newname, vfs->filename[i], mjMAXVFSNAME)==0) {
@@ -210,3 +210,56 @@ void mj_deleteVFS(mjVFS* vfs) {
memset(vfs, 0, sizeof(mjVFS));
}
// open callback for the VFS resource provider
static int vfs_open_callback(mjResource* resource) {
if (!resource || !resource->provider_data || !resource->name) {
return 0;
}
const mjVFS* vfs = (const mjVFS*) resource->provider_data;
return mj_findFileVFS(vfs, resource->name) >= 0;
}
// read callback for the VFS resource provider
static int vfs_read_callback(mjResource* resource, const void** buffer) {
if (!resource || !resource->provider_data) {
*buffer = NULL;
return -1;
}
const mjVFS* vfs = (const mjVFS*) resource->provider_data;
int i = mj_findFileVFS(vfs, resource->name);
if (i < 0) {
*buffer = NULL;
return -1;
}
*buffer = vfs->filedata[i];
return vfs->filesize[i];
}
// close callback for the VFS resource provider
static void vfs_close_callback(mjResource* resource) {
}
// registers a VFS resource provider; returns the index of the provider
int mj_registerVfsProvider(const mjVFS* vfs) {
mjpResourceProvider provider = {
.prefix = mjVFS_PREFIX,
.open = &vfs_open_callback,
.read = &vfs_read_callback,
.close = &vfs_close_callback,
.data = (void*) vfs
};
return mjp_registerResourceProviderInternal(&provider);
}