Engine Adapters¶
← E2E Client | Table Of Contents | Next: Packaging →
An engine adapter owns the core connector as a private implementation, exposing only a surface that
fits each engine's types and thread rules. Core types like result_t<T>, connector_t aren't
revealed in the adapter's public header. See the C++ contract §7
for main thread delivery, callbacks registered by packet name, and per-call request completion.
Unreal Engine¶
Distribution¶
Distributed in .uplugin format. Placed under Plugins/ZLinkStreamConnector/.
Plugins/
└── ZLinkStreamConnector/
├── ZLinkStreamConnector.uplugin
└── Source/
├── ZLinkStreamConnector/ ← Runtime module
└── ZLinkStreamConnectorTests/ ← Automation Test module
Basic Usage¶
The Engine Lobby sample's Actor creates the connector, registers a delegate for the server push ChatNotify, and connects.
void AZLinkClientActor::BeginPlay ()
{
Super::BeginPlay ();
Connector = NewObject<UZLinkStreamConnector> (this);
PacketHandle =
Connector->On (PacketName (engine_lobby::packet::chat_notify),
[this] (const FZLinkStreamPacket &Packet) { HandlePacket (Packet); });
SetStatus (TEXT ("Engine Lobby: connecting"));
Connector->Connect (Endpoint);
if (!Connector->IsConnected ()) {
SetStatus (TEXT ("Engine Lobby: connection failed"), FColor::Red);
return;
}
SendPing ();
}
Pumping the connector from Tick runs the delegates on the Game Thread.
void AZLinkClientActor::Tick (float DeltaSeconds)
{
Super::Tick (DeltaSeconds);
if (Connector != nullptr) {
Connector->Tick (DeltaSeconds);
}
}
Using It From Blueprint¶
Connect, Close, SendJson, RequestJson, On, Dispatch are all BlueprintCallable.
On(PacketName, Delegate) returns a subscription handle, and RequestJson(..., OnCompleted) delivers that request's result to its delegate.
Close() is called automatically on PIE shutdown, map unload, and game instance shutdown.
Running Automation Tests¶
UnrealEditor-Cmd MyProject.uproject \
-ExecCmds="Automation RunTests ZLink.StreamConnector; Quit" \
-unattended -NullRHI
Godot 4¶
Distribution¶
Distributed as a GDExtension source package. Placed under the Godot project's
addons/zlink_stream_connector/.
The .gdextension file registers the built shared library.
Basic Usage (C++)¶
The Engine Lobby sample's node registers a callback for ChatNotify and connects.
void EngineLobbyNode::_ready ()
{
status_ = get_node<Label> ("Status");
chat_subscription_ =
connector_.on (chat_notify, [this] (const auto &packet) { handle_packet (packet); });
const CharString endpoint = endpoint_.utf8 ();
connector_.connect (std::string (endpoint.get_data (), endpoint.length ()));
if (connector_.state () != zlink::godot_stream_connector::connection_state_t::connected) {
fail ("connection failed");
return;
}
connector_.request_json (ping_req, encode_field ("sentAtUnixMs", "1000"), 5.0,
[this] (const auto &result) { handle_ping_response (result); });
set_process (true);
}
It pumps the connector from _process on the Godot main thread.
void EngineLobbyNode::_process (double)
{
if (!failed_) {
connector_.dispatch ();
}
}
Axmol Engine¶
Distribution¶
Distributed as a CMake source package. Include it in the Axmol project's CMakeLists.txt, or
install core via vcpkg/Conan.
add_subdirectory(third_party/zlink_axmol_connector)
target_link_libraries(${APP_NAME} PRIVATE zlink_axmol_connector)
Basic Usage¶
The Engine Lobby sample's Scene registers a callback for ChatNotify and connects.
chat_subscription_ = connector_.on (engine_lobby::packet::chat_notify,
[this] (const auto &packet) { handle_packet (packet); });
connector_.connect (endpoint);
if (connector_.state () != zlink::axmol_stream_connector::connection_state_t::connected) {
set_status ("Engine Lobby: connection failed");
return true;
}
send_ping ();
It pumps the connector from the Axmol scheduler update.
schedule ([this] (float) { connector_.dispatch (); }, "engine-lobby-pump");
Common Engine Adapter API Mapping¶
| Operation | Unreal | Godot | Axmol |
|---|---|---|---|
| Connect | Connect(Endpoint) |
connect(endpoint) |
connect(endpoint) |
| Terminate | Close() |
close() |
close() |
| One-way send | SendJson(Name, Json) |
send_json(name, json) |
send_json(name, json) |
| Request/reply | RequestJson(Name, Json, Timeout, OnCompleted) |
request_json(name, json, timeout, callback) |
request_json(name, json, timeout, callback) |
| Register push | On(PacketName, Delegate) → handle |
on(packet_name, callback) → handle |
on(packet_name, callback) → handle |
| Dispatch | Dispatch() (called from Tick) |
dispatch() (called per frame) |
dispatch() (called per frame) |
| Status change | OnConnectionStateChanged delegate |
on_connection_state_changed callback |
on_connection_state_changed callback |