From 34e5eecba57c52e9142d83d0d1c3b3f790ff9508 Mon Sep 17 00:00:00 2001 From: Matija Kecman Date: Tue, 4 Nov 2025 03:59:28 -0800 Subject: [PATCH] Autogenerate more of mjVFS and mjvGeom WASM bindings PiperOrigin-RevId: 827898643 Change-Id: I95f9eaa129f663cbeb3606d286c2080c47cfbcc4 --- wasm/codegen/generated/bindings.cc | 91 ++++++++++++++++++++-------- wasm/codegen/helpers/helpers_test.py | 8 ++- wasm/codegen/helpers/structs.py | 39 +++++++++--- wasm/codegen/templates/bindings.cc | 34 +---------- 4 files changed, 104 insertions(+), 68 deletions(-) diff --git a/wasm/codegen/generated/bindings.cc b/wasm/codegen/generated/bindings.cc index 123264ba..08a2d501 100644 --- a/wasm/codegen/generated/bindings.cc +++ b/wasm/codegen/generated/bindings.cc @@ -7398,7 +7398,9 @@ MjLROpt& MjLROpt::operator=(const MjLROpt &other) { return *this; } MjLROpt::~MjLROpt() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjLROpt::copy() { return std::make_unique(*this); @@ -7421,7 +7423,9 @@ MjOption& MjOption::operator=(const MjOption &other) { return *this; } MjOption::~MjOption() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjOption::copy() { return std::make_unique(*this); @@ -7443,7 +7447,9 @@ MjStatistic& MjStatistic::operator=(const MjStatistic &other) { return *this; } MjStatistic::~MjStatistic() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjStatistic::copy() { return std::make_unique(*this); @@ -7465,7 +7471,9 @@ MjVisualGlobal& MjVisualGlobal::operator=(const MjVisualGlobal &other) { return *this; } MjVisualGlobal::~MjVisualGlobal() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjVisualGlobal::copy() { return std::make_unique(*this); @@ -7486,7 +7494,9 @@ MjVisualQuality& MjVisualQuality::operator=(const MjVisualQuality &other) { return *this; } MjVisualQuality::~MjVisualQuality() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjVisualQuality::copy() { return std::make_unique(*this); @@ -7507,7 +7517,9 @@ MjVisualHeadlight& MjVisualHeadlight::operator=(const MjVisualHeadlight &other) return *this; } MjVisualHeadlight::~MjVisualHeadlight() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjVisualHeadlight::copy() { return std::make_unique(*this); @@ -7528,7 +7540,9 @@ MjVisualMap& MjVisualMap::operator=(const MjVisualMap &other) { return *this; } MjVisualMap::~MjVisualMap() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjVisualMap::copy() { return std::make_unique(*this); @@ -7549,7 +7563,9 @@ MjVisualScale& MjVisualScale::operator=(const MjVisualScale &other) { return *this; } MjVisualScale::~MjVisualScale() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjVisualScale::copy() { return std::make_unique(*this); @@ -7570,7 +7586,9 @@ MjVisualRgba& MjVisualRgba::operator=(const MjVisualRgba &other) { return *this; } MjVisualRgba::~MjVisualRgba() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjVisualRgba::copy() { return std::make_unique(*this); @@ -7604,7 +7622,9 @@ MjVisual& MjVisual::operator=(const MjVisual &other) { return *this; } MjVisual::~MjVisual() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjVisual::copy() { return std::make_unique(*this); @@ -7626,7 +7646,9 @@ MjSolverStat& MjSolverStat::operator=(const MjSolverStat &other) { return *this; } MjSolverStat::~MjSolverStat() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjSolverStat::copy() { return std::make_unique(*this); @@ -7648,7 +7670,9 @@ MjTimerStat& MjTimerStat::operator=(const MjTimerStat &other) { return *this; } MjTimerStat::~MjTimerStat() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjTimerStat::copy() { return std::make_unique(*this); @@ -7670,7 +7694,9 @@ MjWarningStat& MjWarningStat::operator=(const MjWarningStat &other) { return *this; } MjWarningStat::~MjWarningStat() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjWarningStat::copy() { return std::make_unique(*this); @@ -7692,7 +7718,9 @@ MjContact& MjContact::operator=(const MjContact &other) { return *this; } MjContact::~MjContact() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjContact::copy() { return std::make_unique(*this); @@ -7786,7 +7814,9 @@ MjvPerturb& MjvPerturb::operator=(const MjvPerturb &other) { return *this; } MjvPerturb::~MjvPerturb() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvPerturb::copy() { return std::make_unique(*this); @@ -7809,7 +7839,9 @@ MjvCamera& MjvCamera::operator=(const MjvCamera &other) { return *this; } MjvCamera::~MjvCamera() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvCamera::copy() { return std::make_unique(*this); @@ -7831,23 +7863,24 @@ MjvGLCamera& MjvGLCamera::operator=(const MjvGLCamera &other) { return *this; } MjvGLCamera::~MjvGLCamera() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvGLCamera::copy() { return std::make_unique(*this); } // =============== MjvGeom =============== // -MjvGeom::MjvGeom(mjvGeom *ptr) { ptr_ = ptr; }; +MjvGeom::MjvGeom(mjvGeom *ptr) : ptr_(ptr) {} MjvGeom::MjvGeom() : ptr_(new mjvGeom) { owned_ = true; mjv_initGeom(ptr_, mjGEOM_NONE, nullptr, nullptr, nullptr, nullptr); -}; +} MjvGeom::MjvGeom(const MjvGeom &other) : MjvGeom() { *ptr_ = *other.get(); } -MjvGeom &MjvGeom::operator=( - const MjvGeom &other) { +MjvGeom& MjvGeom::operator=(const MjvGeom &other) { if (this == &other) { return *this; } @@ -7855,7 +7888,9 @@ MjvGeom &MjvGeom::operator=( return *this; } MjvGeom::~MjvGeom() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvGeom::copy() { return std::make_unique(*this); @@ -7877,7 +7912,9 @@ MjvLight& MjvLight::operator=(const MjvLight &other) { return *this; } MjvLight::~MjvLight() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvLight::copy() { return std::make_unique(*this); @@ -7900,7 +7937,9 @@ MjvOption& MjvOption::operator=(const MjvOption &other) { return *this; } MjvOption::~MjvOption() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvOption::copy() { return std::make_unique(*this); @@ -8010,7 +8049,9 @@ MjvFigure& MjvFigure::operator=(const MjvFigure &other) { return *this; } MjvFigure::~MjvFigure() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvFigure::copy() { return std::make_unique(*this); diff --git a/wasm/codegen/helpers/helpers_test.py b/wasm/codegen/helpers/helpers_test.py index 3eae1a0e..0e7e73c7 100644 --- a/wasm/codegen/helpers/helpers_test.py +++ b/wasm/codegen/helpers/helpers_test.py @@ -311,7 +311,9 @@ MjLROpt& MjLROpt::operator=(const MjLROpt &other) { return *this; } MjLROpt::~MjLROpt() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjLROpt::copy() { return std::make_unique(*this); @@ -372,7 +374,9 @@ MjvLight& MjvLight::operator=(const MjvLight &other) { return *this; } MjvLight::~MjvLight() { - if (owned_ && ptr_) delete ptr_; + if (owned_ && ptr_) { + delete ptr_; + } } std::unique_ptr MjvLight::copy() { return std::make_unique(*this); diff --git a/wasm/codegen/helpers/structs.py b/wasm/codegen/helpers/structs.py index befdd1b5..60582e87 100644 --- a/wasm/codegen/helpers/structs.py +++ b/wasm/codegen/helpers/structs.py @@ -493,7 +493,7 @@ def _build_struct_header_internal( return builder.to_string() + ";" -def _get_default_func_name(struct_name: str) -> str: +def _default_function_statement(struct_name: str) -> str: """Returns the default function name for the given struct.""" if ( struct_name in constants.ANONYMOUS_STRUCTS.keys() @@ -505,11 +505,23 @@ def _get_default_func_name(struct_name: str) -> str: ): return "" elif struct_name.startswith("mjs"): - return f"mjs_default{struct_name.removeprefix('mjs')}" + return f"mjs_default{struct_name.removeprefix('mjs')}(ptr_);" + elif struct_name == "mjvGeom": + return ( + "mjv_initGeom(ptr_, mjGEOM_NONE, nullptr, nullptr, nullptr, nullptr);" + ) elif struct_name.startswith("mjv"): - return f"mjv_default{struct_name.removeprefix('mjv')}" + return f"mjv_default{struct_name.removeprefix('mjv')}(ptr_);" else: - return f"mj_default{struct_name.removeprefix('mj')}" + return f"mj_default{struct_name.removeprefix('mj')}(ptr_);" + + +def _delete_ptr_statement(struct_name: str) -> str: + """Returns the delete function name for the given struct.""" + if struct_name == "mjVFS": + return "mj_deleteVFS(ptr_);" + else: + return "delete ptr_;" def _find_fields_with_init( @@ -574,18 +586,19 @@ def build_struct_source( fields_with_init = _find_fields_with_init(wrapped_fields) shallow_copy = use_shallow_copy(wrapped_fields) - mj_default_func = _get_default_func_name(struct_name) fields_init = "" if fields_with_init: fields_init = "".join( field_with_init.initialization for field_with_init in fields_with_init ) + # constructor passing native ptr builder.line( f"{wrapper_name}::{wrapper_name}({struct_name} *ptr) :" f" ptr_(ptr){fields_init} {{}}" ) + # constructor with default values if not is_mjs_struct: with builder.block( @@ -593,10 +606,12 @@ def build_struct_source( f" {struct_name}){fields_init}" ): builder.line("owned_ = true;") - if mj_default_func: - builder.line(f"{mj_default_func}(ptr_);") - # copy constructor + default_func = _default_function_statement(struct_name) + if default_func: + builder.line(default_func) + if shallow_copy and not is_mjs_struct: + # copy constructor with builder.block( f"{wrapper_name}::{wrapper_name}(const {wrapper_name} &other)" + (f" : {wrapper_name}()" if not is_mjs_struct else "") @@ -606,6 +621,7 @@ def build_struct_source( for field_with_init in fields_with_init: if field_with_init.ptr_copy_reset is not None: builder.line(field_with_init.ptr_copy_reset) + # assignment operator with builder.block( f"{wrapper_name}&" @@ -620,18 +636,23 @@ def build_struct_source( if field_with_init.ptr_copy_reset is not None: builder.line(field_with_init.ptr_copy_reset) builder.line("return *this;") + # destructor if is_mjs_struct: builder.line(f"{wrapper_name}::~{wrapper_name}() {{}}") else: with builder.block(f"{wrapper_name}::~{wrapper_name}()"): - builder.line("if (owned_ && ptr_) delete ptr_;") + with builder.block("if (owned_ && ptr_)"): + delete_ptr = _delete_ptr_statement(struct_name) + builder.line(delete_ptr) + # copy function if shallow_copy: with builder.block( f"std::unique_ptr<{wrapper_name}> {wrapper_name}::copy()" ): builder.line(f"return std::make_unique<{wrapper_name}>(*this);") + return builder.to_string() diff --git a/wasm/codegen/templates/bindings.cc b/wasm/codegen/templates/bindings.cc index 8c2597b3..b47a0cf0 100644 --- a/wasm/codegen/templates/bindings.cc +++ b/wasm/codegen/templates/bindings.cc @@ -563,28 +563,7 @@ std::vector MjData::contact() const { // INSERT-GENERATED-MjvGLCamera-CONSTRUCTOR // =============== MjvGeom =============== // -MjvGeom::MjvGeom(mjvGeom *ptr) { ptr_ = ptr; }; -MjvGeom::MjvGeom() : ptr_(new mjvGeom) { - owned_ = true; - mjv_initGeom(ptr_, mjGEOM_NONE, nullptr, nullptr, nullptr, nullptr); -}; -MjvGeom::MjvGeom(const MjvGeom &other) : MjvGeom() { - *ptr_ = *other.get(); -} -MjvGeom &MjvGeom::operator=( - const MjvGeom &other) { - if (this == &other) { - return *this; - } - *ptr_ = *other.get(); - return *this; -} -MjvGeom::~MjvGeom() { - if (owned_ && ptr_) delete ptr_; -} -std::unique_ptr MjvGeom::copy() { - return std::make_unique(*this); -} +// INSERT-GENERATED-MjvGeom-CONSTRUCTOR // =============== MjvLight =============== // // INSERT-GENERATED-MjvLight-CONSTRUCTOR @@ -823,16 +802,7 @@ MjSpec::~MjSpec() { // INSERT-GENERATED-MjsPlugin-CONSTRUCTOR // =============== MjVFS =============== // -MjVFS::MjVFS(mjVFS *ptr) : ptr_(ptr) {} -MjVFS::MjVFS() : ptr_(new mjVFS) { - owned_ = true; - mj_defaultVFS(ptr_); -} -MjVFS::~MjVFS() { - if (owned_ && ptr_) { - mj_deleteVFS(ptr_); - } -} +// INSERT-GENERATED-MjVFS-CONSTRUCTOR // ======= FACTORY AND HELPER FUNCTIONS ========= // std::unique_ptr loadFromXML(std::string filename) {