Ivan FB 1fd1ad07bb
feat(codegen): native C++ typed event handlers
Adds the ergonomic native event surface to the C++ generator:
`node.On<Event>(std::function<void(const <Payload>&)>)` registers a native
listener; a per-event extern "C" trampoline reads the typed POD
(`fromC(*reinterpret_cast<const ::<Payload>*>(msg))`) and invokes the handler —
no CBOR. The handler is owned by the node (a `std::map` of `ListenerBase`) so
its address stays valid until `removeEventListener`.

The example registers `OnEchoFired` and receives a typed `EchoEvent` when Echo
fires it. Verified end-to-end and ASAN-clean.

With this the native C++ generator covers the full surface: requests
(scalar/string/bool/seq/Option/nested), typed struct returns, and typed events.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:39:20 +02:00

42 lines
1.7 KiB
Markdown

# C++ bindings — native (generated)
**Generated** native (zero-serialization) C++ bindings for the timer library —
the C++ counterpart of `c_bindings` / `go_bindings`. The CBOR C++ bindings live
in [`../cpp_bindings`](../cpp_bindings).
| File | Description |
|------|-------------|
| `my_timer_native.hpp` | Generated wrapper: a C++ struct + `toC`/`fromC` per `{.ffi.}` type, and a `My_timerNode` class whose methods marshal typed args into / read typed struct returns out of the native ABI — no CBOR. |
| `my_timer.h` | Native C header (structs + entry points) the `.hpp` includes. |
| `main.cpp`, `Makefile` | A driver + build. |
```cpp
my_timer::My_timerNode node(my_timer::TimerConfig{"my-app"});
std::cout << node.Version();
auto r = node.Echo(my_timer::EchoRequest{"hello", 5}); // -> EchoResponse
std::cout << r.echoed << " / " << r.timerName;
```
Regenerate with `nimble genbindings_cpp_native` (from the repo root).
## Build & run
```sh
cd examples/timer/cpp_native_bindings
make run
```
## Status
Requests are fully supported: scalar / string / bool / nested struct **and now
sequences (`std::vector`) and optionals (`std::optional`)** — create, version,
echo, complex, schedule all generate and round-trip typed values (ASAN-clean).
`toC` uses a holder that owns the C-array backing while string pointers borrow
the C++ argument (valid for the call's duration; the library deep-copies).
Native typed events are supported too: `node.On<Event>(handler)` registers a
native listener and the typed payload arrives via `fromC` (no CBOR). Still to
come: the
native-bare / `_cbor` filename reconciliation (matching the C headers). Today
this emits `my_timer_native.hpp` so it coexists with the CBOR `my_timer.hpp`.