Refactor: Generate all struct bindings within the codegen.
PiperOrigin-RevId: 828973537 Change-Id: I3f371d2f88e1cd9b1bb5c0a9c6a5ace7a21673fb
This commit is contained in:
committed by
Copybara-Service
parent
2c2773e36d
commit
06ecdd6ba1
+1480
-1535
File diff suppressed because it is too large
Load Diff
@@ -65,14 +65,7 @@ class Generator:
|
|||||||
autogenned_struct_source.append(
|
autogenned_struct_source.append(
|
||||||
struct_data.wrapped_source + "\n"
|
struct_data.wrapped_source + "\n"
|
||||||
)
|
)
|
||||||
if struct_data.bindings:
|
autogenned_struct_bindings.append(struct_data.bindings)
|
||||||
autogenned_struct_bindings.append(struct_data.bindings)
|
|
||||||
else:
|
|
||||||
# Bindings with markers
|
|
||||||
markers_and_content.append((
|
|
||||||
f"// INSERT-GENERATED-{struct_data.wrap_name}-BINDINGS",
|
|
||||||
[l.binding for l in struct_data.wrapped_fields],
|
|
||||||
))
|
|
||||||
|
|
||||||
markers_and_content.append((
|
markers_and_content.append((
|
||||||
"// {{ AUTOGENNED_STRUCTS_SOURCE }}",
|
"// {{ AUTOGENNED_STRUCTS_SOURCE }}",
|
||||||
|
|||||||
@@ -47,13 +47,15 @@ class CodeBuilder:
|
|||||||
class IndentBlock:
|
class IndentBlock:
|
||||||
"""Helper class to manage indentation within a `with` statement."""
|
"""Helper class to manage indentation within a `with` statement."""
|
||||||
|
|
||||||
def __init__(self, builder: "CodeBuilder", header_line=""):
|
def __init__(self, builder: "CodeBuilder", header_line="", braces=True):
|
||||||
self._builder = builder
|
self._builder = builder
|
||||||
self._header_line = header_line
|
self._header_line = header_line
|
||||||
|
self._braces = braces
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self):
|
||||||
line = self._header_line
|
line = self._header_line
|
||||||
line += " {" if line else "{"
|
if self._braces:
|
||||||
|
line += " {" if line else "{"
|
||||||
self._builder.line(line)
|
self._builder.line(line)
|
||||||
self._builder._indent_level += 1
|
self._builder._indent_level += 1
|
||||||
self._line_count_enter = len(self._builder._lines)
|
self._line_count_enter = len(self._builder._lines)
|
||||||
@@ -65,20 +67,22 @@ class CodeBuilder:
|
|||||||
if self._line_count_enter == len(self._builder._lines):
|
if self._line_count_enter == len(self._builder._lines):
|
||||||
self._builder._lines[-1] += "}"
|
self._builder._lines[-1] += "}"
|
||||||
else:
|
else:
|
||||||
self._builder.line("}")
|
if self._braces:
|
||||||
|
self._builder.line("}")
|
||||||
|
|
||||||
def block(self, header_line="") -> IndentBlock:
|
def block(self, header_line="", braces=True) -> IndentBlock:
|
||||||
"""Creates a block including braces and an optional header before the opening brace.
|
"""Creates a block including braces and an optional header before the opening brace.
|
||||||
|
|
||||||
Use via a `with` statement.
|
Use via a `with` statement.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
header_line: Optional header line to add before the opening brace.
|
header_line: Optional header line to add before the opening brace.
|
||||||
|
braces: Whether to include opening and closing braces.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
An IndentBlock instance that manages the indentation.
|
An IndentBlock instance that manages the indentation.
|
||||||
"""
|
"""
|
||||||
return self.IndentBlock(self, header_line)
|
return self.IndentBlock(self, header_line, braces)
|
||||||
|
|
||||||
def function(self, signature="") -> IndentBlock:
|
def function(self, signature="") -> IndentBlock:
|
||||||
"""Creates a function."""
|
"""Creates a function."""
|
||||||
|
|||||||
@@ -668,33 +668,38 @@ def _build_struct_bindings(
|
|||||||
wrapped_fields: List[WrappedFieldData],
|
wrapped_fields: List[WrappedFieldData],
|
||||||
):
|
):
|
||||||
"""Builds the C++ bindings for a struct."""
|
"""Builds the C++ bindings for a struct."""
|
||||||
# These structs require specific constructors
|
|
||||||
# which, for now, are hardcoded in the template file.
|
|
||||||
if struct_name in [
|
|
||||||
"mjData",
|
|
||||||
"mjModel",
|
|
||||||
"mjvScene",
|
|
||||||
"mjSpec",
|
|
||||||
]:
|
|
||||||
return ""
|
|
||||||
|
|
||||||
w = common.uppercase_first_letter(struct_name)
|
w = common.uppercase_first_letter(struct_name)
|
||||||
spc = " "
|
|
||||||
builder = code_builder.CodeBuilder()
|
builder = code_builder.CodeBuilder()
|
||||||
builder.line(f"emscripten::class_<{w}>(\"{w}\")")
|
with builder.block(
|
||||||
|
header_line=f'emscripten::class_<{w}>("{w}")', braces=False
|
||||||
|
):
|
||||||
|
if w == "MjData":
|
||||||
|
builder.line(".constructor<MjModel *>()")
|
||||||
|
builder.line(".constructor<const MjModel &, const MjData &>()")
|
||||||
|
elif w == "MjModel":
|
||||||
|
builder.line(
|
||||||
|
'.class_function("loadFromXML", &loadFromXML, take_ownership())'
|
||||||
|
)
|
||||||
|
builder.line(".constructor<const MjModel &>()")
|
||||||
|
elif w == "MjSpec":
|
||||||
|
builder.line(".constructor<const MjSpec &>()")
|
||||||
|
elif w == "MjvScene":
|
||||||
|
builder.line(".constructor<MjModel *, int>()")
|
||||||
|
|
||||||
is_mjs = w.startswith("Mjs")
|
is_mjs = w.startswith("Mjs")
|
||||||
if not is_mjs:
|
if not is_mjs and w not in ["MjData", "MjModel", "MjSpec"]:
|
||||||
builder.line(f"{spc}.constructor<>()")
|
builder.line(".constructor<>()")
|
||||||
|
|
||||||
shallow_copy = use_shallow_copy(wrapped_fields)
|
shallow_copy = use_shallow_copy(wrapped_fields)
|
||||||
if shallow_copy and not is_mjs:
|
if shallow_copy and not is_mjs:
|
||||||
builder.line(f"{spc}.function(\"copy\", &{w}::copy, take_ownership())")
|
builder.line(f'.function("copy", &{w}::copy, take_ownership())')
|
||||||
|
|
||||||
|
for field in wrapped_fields[:-1]:
|
||||||
|
if field.binding:
|
||||||
|
builder.line(field.binding)
|
||||||
|
if wrapped_fields:
|
||||||
|
builder.line(f"{wrapped_fields[-1].binding};")
|
||||||
|
|
||||||
for field in wrapped_fields:
|
|
||||||
if field.binding:
|
|
||||||
builder.line(f"{spc}{field.binding}")
|
|
||||||
builder.line(f"{spc};")
|
|
||||||
return builder.to_string()
|
return builder.to_string()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -597,26 +597,6 @@ std::unique_ptr<MjSpec> parseXMLString(const std::string &xml) {
|
|||||||
|
|
||||||
EMSCRIPTEN_BINDINGS(mujoco_bindings) {
|
EMSCRIPTEN_BINDINGS(mujoco_bindings) {
|
||||||
function("parseXMLString", &parseXMLString, take_ownership());
|
function("parseXMLString", &parseXMLString, take_ownership());
|
||||||
|
|
||||||
emscripten::class_<MjModel>("MjModel")
|
|
||||||
.class_function("loadFromXML", &loadFromXML, take_ownership())
|
|
||||||
.constructor<const MjModel &>()
|
|
||||||
// INSERT-GENERATED-MjModel-BINDINGS
|
|
||||||
;
|
|
||||||
emscripten::class_<MjData>("MjData")
|
|
||||||
.constructor<MjModel *>()
|
|
||||||
.constructor<const MjModel &, const MjData &>()
|
|
||||||
// INSERT-GENERATED-MjData-BINDINGS
|
|
||||||
;
|
|
||||||
emscripten::class_<MjvScene>("MjvScene")
|
|
||||||
.constructor<>()
|
|
||||||
.constructor<MjModel *, int>()
|
|
||||||
// INSERT-GENERATED-MjvScene-BINDINGS
|
|
||||||
;
|
|
||||||
emscripten::class_<MjSpec>("MjSpec")
|
|
||||||
.constructor<const MjSpec &>()
|
|
||||||
// INSERT-GENERATED-MjSpec-BINDINGS
|
|
||||||
;
|
|
||||||
// {{ AUTOGENNED_STRUCTS_BINDINGS }}
|
// {{ AUTOGENNED_STRUCTS_BINDINGS }}
|
||||||
|
|
||||||
// TODO: should be generated in future CLs -- //
|
// TODO: should be generated in future CLs -- //
|
||||||
|
|||||||
Reference in New Issue
Block a user