Add modified callback to resource providers (for caching purposes).
PiperOrigin-RevId: 561327623 Change-Id: Id6683f6d6d32ee91019aba46599c28cbffe29df6
This commit is contained in:
committed by
Copybara-Service
parent
273c23038c
commit
16ee0dfde5
@@ -269,6 +269,7 @@ bool ResourceProvidersAreIdentical(const mjpResourceProvider* p1, const mjpResou
|
||||
p1->read == p2->read &&
|
||||
p1->close == p2->close &&
|
||||
p1->getdir == p2->getdir &&
|
||||
p1->modified == p2->modified &&
|
||||
p1->data == p2->data);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#define stat _stat
|
||||
#endif
|
||||
|
||||
#include <mujoco/mjplugin.h>
|
||||
#include "engine/engine_plugin.h"
|
||||
@@ -28,6 +39,7 @@
|
||||
typedef struct {
|
||||
uint8_t* buffer; // raw bytes from file
|
||||
size_t nbuffer; // size of buffer in bytes
|
||||
time_t mtime; // last modified time
|
||||
} file_buffer;
|
||||
|
||||
// open the given resource; if the name doesn't have a prefix matching with a
|
||||
@@ -77,6 +89,13 @@ mjResource* mju_openResource(const char* name) {
|
||||
mju_closeResource(resource);
|
||||
return NULL;
|
||||
}
|
||||
struct stat file_stat;
|
||||
if (stat(name, &file_stat) == 0) {
|
||||
memcpy(&fb->mtime, &file_stat.st_mtime, sizeof(time_t));
|
||||
} else {
|
||||
memset(&fb->mtime, 0, sizeof(time_t));
|
||||
}
|
||||
|
||||
return resource;
|
||||
}
|
||||
|
||||
@@ -149,6 +168,40 @@ void mju_getResourceDir(mjResource* resource, const char** dir, int* ndir) {
|
||||
|
||||
|
||||
|
||||
// modified callback for OS filesystem
|
||||
static int mju_isModifiedFile(const char* name, const file_buffer* fb) {
|
||||
if (fb != NULL) {
|
||||
struct stat file_stat;
|
||||
if (stat(name, &file_stat) == 0) {
|
||||
return difftime(fb->mtime, file_stat.st_mtime) < 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Returns > 0 if resource has been modified since last read, 0 if not, and < 0
|
||||
// if inconclusive
|
||||
int mju_isModifiedResource(const mjResource* resource) {
|
||||
if (resource == NULL) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
// provider is not OS filesystem
|
||||
if (resource->provider) {
|
||||
if (resource->provider->modified) {
|
||||
return resource->provider->modified(resource);
|
||||
}
|
||||
return 1; // default (modified)
|
||||
}
|
||||
|
||||
return mju_isModifiedFile(resource->name, (file_buffer*) resource->data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// get the length of the dirname portion of a given path
|
||||
int mju_dirnamelen(const char* path) {
|
||||
if (!path) {
|
||||
|
||||
@@ -274,6 +274,7 @@ mjResource* mju_openVfsResource(const char* name, const mjVFS* vfs) {
|
||||
.read = &vfs_read_callback,
|
||||
.close = &vfs_close_callback,
|
||||
.getdir = &vfs_getdir_callback,
|
||||
.modified = NULL
|
||||
};
|
||||
|
||||
// create resource
|
||||
|
||||
Reference in New Issue
Block a user