PlatformModule and registry API
Declared by <huxerui/platform_registry.h> and <huxerui/root.h>; all shared declarations are in huxerui.
A PlatformModule is a registered C++ service, not a required base class. Direct C++ integrations keep their own typed methods. Use PlatformChannel only when a Java or JavaScript instance needs a request/event bridge. The registry implementation in huxerui::detail is not an application API.
Register and open a typed service
Section titled “Register and open a typed service”| Operation | Contract |
|---|---|
RootContext::RegisterPlatformModule<Module>(name, factory) |
Factory takes PlatformAdapter& and returns exactly Module. |
RegisterPlatformModule<Module, Options>(name, factory) |
Factory also receives const Options&. |
RootContext::OpenPlatformModule<Module>(name[, options]) |
Opens during root installation. |
OpenPlatformModule<Module>(name[, options]) |
Opens from committed Lifecycle setup, not during composition or from an arbitrary event handler. |
RootContext::Provide<Service>(shared_ptr) |
Makes a root-owned service available through UseService<Service>(). |
Names are case-sensitive and shared by module and view registrations. Install before first composition; registration freezes after root hooks complete. The registered result/options types must match the requested types. Missing or incompatible registrations are errors, not implicit fallback factories.
PlatformChannel
Section titled “PlatformChannel”A copyable handle to one shared asynchronous channel. A default-constructed channel is closed.
IsOpen()reports whether it accepts work.Invoke<Result>(method, arguments, completion)returnsPlatformRequestId. Primitive arguments convert automatically; structured value types provide staticEncode/Decodeoperations.Invoke<Result>(method, completion)sends a null argument. Usestd::monostatefor a null result.- The raw
Invokeoverload exchangesPlatformPayload. On<Key>(handler)subscribes to a named typed event;On(name, handler)receives raw payloads.Cancel(id)invalidates a pending request and returns false if it already ended or is unknown.Close()closes all copies, cancels pending work, disconnects events, and disposes the platform instance.
Invocations, completions, and events are serialized through the owning UI dispatcher. Completion is at most once, not guaranteed after cancellation. A malformed result becomes a PlatformError with code huxerui/invalid-result. PlatformResult<T> is a value-or-PlatformError variant; the error carries code, message, and details.
This complete translation unit demonstrates the bridge boundary; its caller supplies an already-open channel from its platform integration:
#include <huxerui/huxerui.h>
#include <string>#include <variant>
using namespace huxerui;
PlatformRequestId ReadTitle(const PlatformChannel& channel, State<std::string> status) { return channel.Invoke<std::string>("readTitle", std::monostate{}, [status](PlatformResult<std::string> result) { if (const auto* error = std::get_if<PlatformError>(&result)) { status = error->message; } else { status = std::get<std::string>(result); } });}Events and payloads
Section titled “Events and payloads”PlatformEventEmitter sends an event from a platform implementation. A direct C++ Emit<Key>(value) requires the exact declared value type. PlatformView event keys derive from Event<...> and supply a stable Name; .On<Key>() installs the handler directly. There is no separate event declaration list.
Direct PlatformView events run synchronously on the UI thread and may return an optional result; channel notifications are asynchronous void events. Do not rely on a disconnected emitter delivering output.
PlatformPayload is an immutable shared value. PlatformPayloadKind has Null, Boolean, Integer, Double, String, Bytes, List, Object, ExternalTexture, and FileReference alternatives. Constructors validate values; Kind(), IsNull(), and the corresponding As... accessor inspect them. A mismatched accessor throws.
PlatformPayloadEnvelope retains serialized bytes and the external_textures and file_references capability tables. Preserve the complete envelope when encoding/decoding a bridge message. Copying just the bytes loses capabilities; a file reference is not interchangeable with a path string.
Keep payload serialization at a cross-language boundary. Do not wrap direct C++ service options or controlled view properties in payloads merely to use the registry.
See PlatformModule guide, PlatformView API, and platform-specific interfaces.
Buffer payloads
Section titled “Buffer payloads”PlatformPayloadKind::BufferReference, the BufferReference constructor overload, and AsBufferReference retain CPU storage rather than encoding its bytes. Typed ToPayload/FromPayload paths support the same value. The bridge must explicitly support this retained capability; Web rejects it. Encode remains a capability-free serialization operation and cannot persist buffers, FileReference or ExternalTexture.
Keep producer memory address-stable and synchronize access. See data ownership and platform buffer integration.

