Expose mju resource functions to public header.

Many of these functions are useful when writing a custom decoder.

PiperOrigin-RevId: 868321921
Change-Id: I7e0dd285e0559b6f486acf8cbf4376ff8d91943d
This commit is contained in:
Sam Haves
2026-02-10 14:30:38 -08:00
committed by Copybara-Service
parent 210cf86486
commit 6715a0ceaa
7 changed files with 275 additions and 0 deletions
+1
View File
@@ -29,6 +29,7 @@ API function can be classified as:
- :ref:`Printing<Printing>` of various quantities.
- :ref:`Virtual file system<Virtualfilesystem>`, used to load assets from memory.
- :ref:`Asset cache<Assetcache>`, used to speed up model compilation.
- :ref:`Resources<Resources>`, interfacing with resource providers to load assets.
- :ref:`Initialization<Initialization>` of data structures.
- :ref:`Error and memory<Errorandmemory>`.
- :ref:`Miscellaneous<Miscellaneous>` functions.
+71
View File
@@ -1551,6 +1551,77 @@ Get the internal asset cache used by the compiler.
Clear the asset cache.
.. _Resources:
Resources
^^^^^^^^^
Resources are the interface between :ref:`resource providers <exProvider>` and MuJoCo model compilation code.
These functions provide the means to query the resource provider and obtain resources.
.. _mju_openResource:
`mju_openResource <#mju_openResource>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mju_openResource
Open a resource; if the name doesn't have a prefix matching a registered resource provider,
then the OS filesystem is used.
*Nullable:* ``dir``, ``vfs``, ``error``
.. _mju_closeResource:
`mju_closeResource <#mju_closeResource>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mju_closeResource
Close a resource; no-op if resource is NULL.
.. _mju_readResource:
`mju_readResource <#mju_readResource>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mju_readResource
Set buffer to bytes read from the resource and return number of bytes in buffer;
return negative value if error.
.. _mju_getResourceDir:
`mju_getResourceDir <#mju_getResourceDir>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mju_getResourceDir
For a resource with a name partitioned as {dir}{filename}, get the dir and ndir pointers.
.. _mju_isModifiedResource:
`mju_isModifiedResource <#mju_isModifiedResource>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mju_isModifiedResource
Compare resource timestamp to provided timestamp.
Return 0 if timestamps match, >0 if resource is newer, <0 if resource is older.
.. _mju_decodeResource:
`mju_decodeResource <#mju_decodeResource>`__
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. mujoco-include:: mju_decodeResource
Find the decoder for a resource and return the decoded spec.
The caller takes ownership of the spec and is responsible for cleaning it up.
*Nullable:* ``vfs``
.. _Initialization:
Initialization
+5
View File
@@ -816,3 +816,8 @@ Note that derivatives depend only on :math:`h` and :math:`v` (in fact, on :math:
All outputs are optional.
*Nullable:* ``Dquat``, ``Dvel``, ``Dscale``
.. _Resources:
Resources are the interface between :ref:`resource providers <exProvider>` and MuJoCo model compilation code.
These functions provide the means to query the resource provider and obtain resources.
+8
View File
@@ -3579,6 +3579,14 @@ const mjpResourceProvider* mjp_getResourceProviderAtSlot(int slot);
void mjp_registerDecoder(const mjpDecoder* decoder);
void mjp_defaultDecoder(mjpDecoder* decoder);
const mjpDecoder* mjp_findDecoder(const mjResource* resource, const char* content_type);
mjResource* mju_openResource(const char* dir, const char* name,
const mjVFS* vfs, char* error, size_t nerror);
void mju_closeResource(mjResource* resource);
int mju_readResource(mjResource* resource, const void** buffer);
void mju_getResourceDir(mjResource* resource, const char** dir, int* ndir);
int mju_isModifiedResource(const mjResource* resource, const char* timestamp);
mjSpec* mju_decodeResource(mjResource* resource, const char* content_type,
const mjVFS* vfs);
mjThreadPool* mju_threadPoolCreate(size_t number_of_threads);
void mju_bindThreadPool(mjData* d, void* thread_pool);
void mju_threadPoolEnqueue(mjThreadPool* thread_pool, mjTask* task);
+30
View File
@@ -1522,6 +1522,36 @@ MJAPI void mjp_defaultDecoder(mjpDecoder* decoder);
// If no match, return NULL.
MJAPI const mjpDecoder* mjp_findDecoder(const mjResource* resource, const char* content_type);
//---------------------------------- Resources -----------------------------------------------------
// Open a resource; if the name doesn't have a prefix matching a registered resource provider,
// then the OS filesystem is used.
// Nullable: dir, vfs, error
MJAPI mjResource* mju_openResource(const char* dir, const char* name,
const mjVFS* vfs, char* error, size_t nerror);
// Close a resource; no-op if resource is NULL.
MJAPI void mju_closeResource(mjResource* resource);
// Set buffer to bytes read from the resource and return number of bytes in buffer;
// return negative value if error.
MJAPI int mju_readResource(mjResource* resource, const void** buffer);
// For a resource with a name partitioned as {dir}{filename}, get the dir and ndir pointers.
MJAPI void mju_getResourceDir(mjResource* resource, const char** dir, int* ndir);
// Compare resource timestamp to provided timestamp.
// Return 0 if timestamps match, >0 if resource is newer, <0 if resource is older.
MJAPI int mju_isModifiedResource(const mjResource* resource, const char* timestamp);
// Find the decoder for a resource and return the decoded spec.
// The caller takes ownership of the spec and is responsible for cleaning it up.
// Nullable: vfs
MJAPI mjSpec* mju_decodeResource(mjResource* resource, const char* content_type,
const mjVFS* vfs);
//---------------------------------- Threads -------------------------------------------------------
// Create a thread pool with the specified number of threads running.
+154
View File
@@ -9600,6 +9600,160 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
),
doc='Return the resource provider with the prefix that matches against the resource name. If no match, return NULL.', # pylint: disable=line-too-long
)),
('mju_openResource',
FunctionDecl(
name='mju_openResource',
return_type=PointerType(
inner_type=ValueType(name='mjResource'),
),
parameters=(
FunctionParameterDecl(
name='dir',
type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
nullable=True,
),
FunctionParameterDecl(
name='name',
type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
),
FunctionParameterDecl(
name='vfs',
type=PointerType(
inner_type=ValueType(name='mjVFS', is_const=True),
),
nullable=True,
),
FunctionParameterDecl(
name='error',
type=PointerType(
inner_type=ValueType(name='char'),
),
nullable=True,
),
FunctionParameterDecl(
name='nerror',
type=ValueType(name='size_t'),
),
),
doc="Open a resource; if the name doesn't have a prefix matching a registered resource provider, then the OS filesystem is used.", # pylint: disable=line-too-long
)),
('mju_closeResource',
FunctionDecl(
name='mju_closeResource',
return_type=ValueType(name='void'),
parameters=(
FunctionParameterDecl(
name='resource',
type=PointerType(
inner_type=ValueType(name='mjResource'),
),
),
),
doc='Close a resource; no-op if resource is NULL.',
)),
('mju_readResource',
FunctionDecl(
name='mju_readResource',
return_type=ValueType(name='int'),
parameters=(
FunctionParameterDecl(
name='resource',
type=PointerType(
inner_type=ValueType(name='mjResource'),
),
),
FunctionParameterDecl(
name='buffer',
type=PointerType(
inner_type=PointerType(
inner_type=ValueType(name='void', is_const=True),
),
),
),
),
doc='Set buffer to bytes read from the resource and return number of bytes in buffer; return negative value if error.', # pylint: disable=line-too-long
)),
('mju_getResourceDir',
FunctionDecl(
name='mju_getResourceDir',
return_type=ValueType(name='void'),
parameters=(
FunctionParameterDecl(
name='resource',
type=PointerType(
inner_type=ValueType(name='mjResource'),
),
),
FunctionParameterDecl(
name='dir',
type=PointerType(
inner_type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
),
),
FunctionParameterDecl(
name='ndir',
type=PointerType(
inner_type=ValueType(name='int'),
),
),
),
doc='For a resource with a name partitioned as {dir}{filename}, get the dir and ndir pointers.', # pylint: disable=line-too-long
)),
('mju_isModifiedResource',
FunctionDecl(
name='mju_isModifiedResource',
return_type=ValueType(name='int'),
parameters=(
FunctionParameterDecl(
name='resource',
type=PointerType(
inner_type=ValueType(name='mjResource', is_const=True),
),
),
FunctionParameterDecl(
name='timestamp',
type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
),
),
doc='Compare resource timestamp to provided timestamp. Return 0 if timestamps match, >0 if resource is newer, <0 if resource is older.', # pylint: disable=line-too-long
)),
('mju_decodeResource',
FunctionDecl(
name='mju_decodeResource',
return_type=PointerType(
inner_type=ValueType(name='mjSpec'),
),
parameters=(
FunctionParameterDecl(
name='resource',
type=PointerType(
inner_type=ValueType(name='mjResource'),
),
),
FunctionParameterDecl(
name='content_type',
type=PointerType(
inner_type=ValueType(name='char', is_const=True),
),
),
FunctionParameterDecl(
name='vfs',
type=PointerType(
inner_type=ValueType(name='mjVFS', is_const=True),
),
nullable=True,
),
),
doc='Find the decoder for a resource and return the decoded spec. The caller takes ownership of the spec and is responsible for cleaning it up.', # pylint: disable=line-too-long
)),
('mju_threadPoolCreate',
FunctionDecl(
name='mju_threadPoolCreate',
+6
View File
@@ -185,7 +185,13 @@ _SKIPPED_GETTERS_AND_SETTERS: tuple[str, ...] = (
_SKIPPED_UTILITY_FUNCTIONS: tuple[str, ...] = (
# go/keep-sorted start
"mj_readSensor",
"mju_closeResource",
"mju_decodeResource",
"mju_getResourceDir",
"mju_getXMLDependencies",
"mju_isModifiedResource",
"mju_openResource",
"mju_readResource",
# go/keep-sorted end
)