Reads MuJoCo's C headers into data.
MuJoCo generates its own Python bindings the same way — python/mujoco/introspect
parses the headers and checks the result in. This is the same idea in Elixir: the
headers are the source of truth, the catalogue is checked in beside us, and
mix ex_mujoco.gen --check proves the two agree.
Three things are read:
- functions — every
MJAPIdeclaration inmujoco.hand the headers it includes; - structs — the members of
mjModelandmjData, with the dimensions of their arrays taken frommjxmacro.h, which exists to be read like this; - enums — every
typedef enum mjtX { … } mjtX;.
Nothing here decides what is bound; it only says what exists. ExMujoco.Gen
holds that decision, in c_src/manifest.exs.
Summary
Types
A C type as it appears in a declaration: mjtNum*, const char*.
Functions
What a member is, as far as a binding goes.
What an array of this element type is, as {tag, cpp_type}.
Every typedef enum mjtX { … } mjtX; in one header.
The MJAPI declarations in one header.
Everything the headers say, as one map.
The members of one of MuJoCo's structs, with array dimensions from mjxmacro.h.
Why a member cannot be read as an array, when it cannot.
Types
@type ctype() :: %{name: String.t(), const: boolean(), pointers: non_neg_integer()}
A C type as it appears in a declaration: mjtNum*, const char*.
Functions
What a member is, as far as a binding goes.
:integerand:float— one value of the struct, returned as is;:array— a binary of elements plus its two extents;:unsupported— nothing a caller can name, with the reason why.
What an array of this element type is, as {tag, cpp_type}.
Every typedef enum mjtX { … } mjtX; in one header.
@spec functions_in(Path.t()) :: [function_decl()]
The MJAPI declarations in one header.
@spec read(Path.t()) :: %{ functions: [function_decl()], structs: %{required(String.t()) => [member()]}, enums: [enum()], version: non_neg_integer() | nil }
Everything the headers say, as one map.
dir is a MuJoCo include root, the one MUJOCO_DIR names: it must hold
mujoco/mujoco.h.
The members of one of MuJoCo's structs, with array dimensions from mjxmacro.h.
Value members (mjtSize nq) and pointers (mjtNum* geom_pos) are both here,
because a caller reads both. Arrays declared inline (mjtNum solver_fwdinv[2])
carry their dimension in the declaration; a pointer carries it in the X-macro
lists, which is where MuJoCo itself gets it for mjvScene and the bindings.
Why a member cannot be read as an array, when it cannot.