Generate the ``mjs_setToX(Element, ...)`` call inside CODEGEN_EXPORT from the function's signature in the mjspec snapshot. Replaces the hand- written multi-line C++ literals that used to live in ``codegen_rules.json``. Marshaling rules per function parameter ``p`` (``c_type``, ``array_d
(
subtype_key: str,
setto_rules: Dict[str, Any],
rules: Dict[str, Any],
mjspec: Dict[str, Any] | None,
subtype_schema_attrs: List[str],
base_schema_attrs: Sequence[str],
)
| 1938 | |
| 1939 | |
| 1940 | def _emit_setto_call( |
| 1941 | subtype_key: str, |
| 1942 | setto_rules: Dict[str, Any], |
| 1943 | rules: Dict[str, Any], |
| 1944 | mjspec: Dict[str, Any] | None, |
| 1945 | subtype_schema_attrs: List[str], |
| 1946 | base_schema_attrs: Sequence[str], |
| 1947 | ) -> str: |
| 1948 | """Generate the ``mjs_setToX(Element, ...)`` call inside CODEGEN_EXPORT |
| 1949 | from the function's signature in the mjspec snapshot. Replaces the hand- |
| 1950 | written multi-line C++ literals that used to live in ``codegen_rules.json``. |
| 1951 | |
| 1952 | Marshaling rules per function parameter ``p`` (``c_type``, ``array_dim``): |
| 1953 | - ``double`` scalar + UE ``float`` -> ``bOverride_p ? (double)p : <sentinel>`` |
| 1954 | - ``double`` scalar + UE ``FVector`` + projection ``X`` |
| 1955 | -> ``bOverride_p ? (double)p.X : <sentinel>`` |
| 1956 | - ``double[N]`` array + UE ``TArray<float>`` |
| 1957 | -> ``double pBuf[N] = { ... }; pass pBuf`` |
| 1958 | - ``double[1]`` array + UE ``float`` (scalar-in-buffer) |
| 1959 | -> ``double pBuf[1] = { ... }; pass pBuf`` |
| 1960 | - ``int`` scalar -> ``bOverride_p ? (int)p : <sentinel>`` |
| 1961 | - Params NOT present in subtype/base schema -> force sentinel. |
| 1962 | |
| 1963 | Sentinels: defaults come from ``setto_param_defaults`` in the rules JSON, |
| 1964 | keyed by ``(function_name, param_name)``; otherwise ``-1.0`` for doubles, |
| 1965 | ``0`` for ints. The dcmotor pattern (``nullable_arrays``) emits |
| 1966 | ``bOverride_X ? Buf : nullptr`` and uses the ``FillDouble`` helper that |
| 1967 | lives file-local in ``MjDcMotorActuator.cpp``. |
| 1968 | """ |
| 1969 | if setto_rules is None: |
| 1970 | return "" |
| 1971 | fn_name = setto_rules.get("call") |
| 1972 | if not fn_name: |
| 1973 | return "" |
| 1974 | if not mjspec or fn_name not in mjspec.get("setto_functions", {}): |
| 1975 | raise RuntimeError( |
| 1976 | f"mjs_setTo* function '{fn_name}' not found in the projected " |
| 1977 | f"mjspec. Rebuild the introspect snapshot via " |
| 1978 | f"`python Scripts/codegen/build_introspect_snapshot.py`." |
| 1979 | ) |
| 1980 | sig = mjspec["setto_functions"][fn_name] |
| 1981 | if not sig["params"]: |
| 1982 | return ( |
| 1983 | f" {{\n" |
| 1984 | f" const char* SetToErr = {fn_name}(Element);\n" |
| 1985 | f" if (SetToErr && *SetToErr)\n" |
| 1986 | f" {{\n" |
| 1987 | f" UE_LOG(LogURLabBind, Warning, TEXT(\"{fn_name} on '%s': %s\"), " |
| 1988 | f"*GetName(), UTF8_TO_TCHAR(SetToErr));\n" |
| 1989 | f" }}\n" |
| 1990 | f" }}\n" |
| 1991 | ) |
| 1992 | |
| 1993 | type_mappings: Dict[str, str] = rules.get("type_mappings", {}) |
| 1994 | default_type: str = rules.get("default_type", "float") |
| 1995 | fn_defaults: Dict[str, str] = rules.get("setto_param_defaults", {}).get(fn_name, {}) |
| 1996 | param_renames: Dict[str, str] = setto_rules.get("param_renames", {}) |
| 1997 | projections: Dict[str, str] = setto_rules.get("projections", {}) |
no outgoing calls