4 Commits

Author SHA1 Message Date
Ivan FB
ceccc7bef3
feat(codegen): Go per-event typed native event handlers
Adds the ergonomic native event surface for Go: `node.On<Event>(func(<Payload>))`
registers a native listener for that event and the library delivers the typed
`<Payload>` POD, which an exported Go callback reads into a Go struct (reusing
the generated `fromC`) and hands to the user's handler — no CBOR parsing. Sits
beside the existing CBOR `SetEventHandler` (wildcard / inter-process).

The example registers `OnEchoFired` and receives a typed `EchoEvent` when Echo
fires it. Verified end-to-end with `go run -race`.

C/C++/Rust get the same per-event typed handler + router next.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:37:27 +02:00
Ivan FB
918dd72390
feat(ffi): native event delivery + dual-ABI event symbol naming
Events now mirror the native/CBOR split already in place for requests, with the
same symbol-naming convention:

- `<lib>_add_event_listener`      -> NATIVE listener (typed `<T>Pod` by pointer)
- `<lib>_add_event_listener_cbor` -> CBOR listener (EventEnvelope bytes)

Framework: `FFIEventListener` gains a `native` flag; `addEventListener` a
`native` param; a new `dispatchFFIEventDual` template builds the `<T>Pod` once
for native listeners (`nimToPod`/`freePod`) and the CBOR envelope once for the
rest, fanning each out — so a single `{.ffiEvent.}` dispatch serves both kinds.
`declareLibrary` exports both registration entry points.

Generators: the bare `<lib>_add_event_listener` is the native symbol; every
CBOR consumer (C/C++/Go/Rust) now targets `<lib>_add_event_listener_cbor`. The
rename and the generator updates ship together so the bare name is never briefly
broken. Bindings regenerated.

Validated: native-event unit test (typed POD to native + CBOR to cbor listener,
orc/refc/ASAN); full unit suite; C++ e2e 19/19; Go example; existing event
tests unchanged. The per-event *typed* native callback + wildcard router (the
ergonomic consumer surface) is a follow-up.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:37:27 +02:00
Ivan FB
0a8b53a06d
feat(codegen): Go bindings return typed structs natively
Struct-returning methods now hand back a typed Go struct instead of the raw
CBOR/bytes. Since the native return POD is freed right after the callback, the
POD->Go conversion must happen in-callback: the generator emits a `fromC()`
reader per {.ffi.} type and, per struct-returning proc, an exported Go result
callback. The method calls the native entry point directly with that callback
and a `runtime/cgo.Handle` (boxed in a small C allocation so it travels through
the void* userData checkptr-safe), then blocks until the callback delivers the
typed value or error on the result slot.

String/raw-returning procs keep the existing C-bridge + condvar path. Validated
end-to-end (Echo/Complex/Schedule) including under `go run -race`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 18:37:19 +02:00
Ivan FB
965fd68785
feat(codegen): Go bindings support struct/seq/Option params
The Go generator previously emitted a `// SKIPPED` stub for any proc with a
struct, sequence or optional parameter, leaving Echo/Complex/Schedule
uncallable. Now that the native ABI carries those as flat C-POD structs, the Go
side can marshal them: emit an idiomatic Go struct per {.ffi.} type plus a
`toC()` that builds the matching `C.<Type>` (C.CString for strings, a C array
for seqs, present-flags for options, recursively for nested structs) and
returns cleanup funcs run via defer once the call returns. The native path
deep-copies every argument, so releasing the C buffers immediately is safe.

The C bridge already accepted struct-by-value params via the pass-through type
mapping; only the Go-side conversion and the `allSupported` gate needed work.
Bare seq/Option *top-level* params (not wrapped in a struct) remain skipped, as
the native ABI does not expose them either.

The generated package is now self-contained: the native `<lib>.h` is emitted
beside the `.go`, and the cgo directives use ${SRCDIR} so the header and the
staged library resolve without extra env vars. genbindings_go runs gofmt to
finalize column alignment.

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