Add args field to mjResource for decoder and encoder arguments.

Add an optional `const char* args` field to `mjResource` to allow passing
resource arguments/hints (such as requested channel count or encoding options)
to resource decoders and encoders.

PiperOrigin-RevId: 959774058
Change-Id: Icc41a2bb3895fef24f98c5fa9a77cdad092a6bc7
This commit is contained in:
Sam Haves
2026-08-05 11:30:42 -07:00
committed by Copybara-Service
parent 83e621d771
commit 596b6f433d
5 changed files with 74 additions and 0 deletions
+44
View File
@@ -16,6 +16,10 @@
#include <string.h>
#include <cstdlib>
#include <cstring>
#include <string_view>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mujoco/mjmodel.h>
@@ -118,5 +122,45 @@ TEST_F(DecoderPluginTest, CanDecode) {
mj_deleteSpec(spec);
}
TEST_F(DecoderPluginTest, DecodeWithResourceArgs) {
static auto decode_args_fn =
+[](mjResource* resource, const mjVFS* vfs) -> mjSpec* {
mjSpec* s = MakeSimpleSpec();
if (resource && resource->args) {
std::string_view args_view(resource->args);
size_t pos = args_view.find("size=");
if (pos != std::string_view::npos) {
mjsElement* elem = mjs_firstElement(s, mjOBJ_GEOM);
mjsGeom* geom = mjs_asGeom(elem);
if (geom) {
geom->size[0] = std::atof(args_view.data() + pos + 5);
}
}
}
return s;
};
mjpDecoder decoder;
mjp_defaultDecoder(&decoder);
decoder.content_type = "model/argsformat";
decoder.extension = ".argsformat";
decoder.can_decode = +[](const mjResource* r) -> int { return 1; };
decoder.decode = decode_args_fn;
mjp_registerDecoder(&decoder);
mjResource resource;
std::memset(&resource, 0, sizeof(resource));
resource.name = const_cast<char*>("test.argsformat");
resource.args = "size=42.0&foo=bar";
mjSpec* spec = mju_decodeResource(&resource, "model/argsformat", nullptr);
ASSERT_THAT(spec, testing::NotNull());
mjsElement* elem = mjs_firstElement(spec, mjOBJ_GEOM);
mjsGeom* geom = mjs_asGeom(elem);
ASSERT_THAT(geom, testing::NotNull());
EXPECT_DOUBLE_EQ(geom->size[0], 42.0);
mj_deleteSpec(spec);
}
} // namespace
} // namespace mujoco