COMMUNICATION API
The functions here are designed to enable cross-module communication, whether it is between two WASM modules, or a WASM module and a JS gauge, or a WASM module and a SimConnect client. You can find more information on the other platform functions from the following links:
When using this API it's worth noting the following:
- JSON is a good way to format data for communication between the different platforms. In C++, a version of RapidJSON is provided as part of the SDK - with some fixes to work in Web Assembly - and can help you when sharing information.
- You can add an ID in function arguments to know the caller, and ensure you are dealing with the correct events.
- All calls are asynchronous.
You can find a sample project to use as a reference when using the Communication API here:
There are also debugging tools available in DevMode which can be used to help debug Flow Events and Communication API events, which are described on the following page:
Functions
The following functions are available for the Communication API:
| Function | Description |
|---|---|
fsCommBusRegister |
Register a WASM communication event. |
fsCommBusUnregister |
Unregister one or more WASM communication events. |
fsCommBusUnregisterOneEvent |
Unregister a single WASM communication event. |
fsCommBusUnregisterAll |
Unregister all WASM communication events. |
fsCommBusCall |
Call an event registered in a WASM or JS module. |
Enums/Structs
The enums and structs available for use with the Communication API are:
| Enum / Struct Name | Description | Type |
|---|---|---|
FsCommBusBroadcastFlags |
This enum is used to specified the type of module/gauge to broadcast an event call to. | Enum |
Typedefs
When using the functions listed above, you'll need to also have the following type definitions, as they will be used as return values or to create callbacks by many of the functions. These typedefs are:
-
fsCommBusWasmCallback
This is the type that needs to be used for callbacks in WASM:
typedef void (*fsCommBusWasmCallback)( const char* buf, unsigned int bufSize )
Calling And Registering Events
The communication (CommBus) API is cross platform, and as such, can be used to call and register events on the different supported platforms. Below you can find brief overviews for how this can be done, per-platform.
Register an event in Wasm
Create a callback
static void MyWasmCallback(const char* args, unsigned int size, void* ctx) { ... }
Register the event
fsCommBusRegister("MyWasmCallback", MyWasmCallback);
Call JS from WASMCall JS from WASM
In your JS file you need to create the callback:
myJsCallback(args) { ... }
You then need to register the view listener:
this.commBusListener = RegisterCommBusListener();
Next you would connect the callback to an event name:
this.commBuListener.on("MyJsCallback", this.myJsCallback);
Finally, in the WASM module you would call the event:
fsCommBusCall("MyJsCallback", "{value : 42}", bufferSize, FsCallFlags::FsCall_JS)
Call WASM from WASMCall WASM from WASM
First, create the callback in the first WASM module:
static void MyWasmCallback(const char* args, unsigned int size, void* ctx) { ... }
Then register the callback as well:
fsCommBusRegister("MyWasmCallback", MyWasmCallback);
It is possible to add a pointer to a context. This pointer will be retrieved in the callback in the ctx argument:
void* ctx = something;
fsCommBusRegister("MyWasmCallback", MyWasmCallback, ctx);
In the second (or third or forth) WASM module you would then call the event:
fsCommBusCall("MyWasmCallback", "{value : 42}", 13, FsCallFlags::FsCall_Wasm);
Call SimConnect (C++ / C#) from WASMCall SimConnect (C++ / C#) from WASM
In your SimConnect, connect a client and call a dispatch proc:
#include "SimConnect.h"
HANDLE hSimConnect = NULL;
void CALLBACK MyDispatchProcSO(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext)
{
// Dispacth
}
int main()
{
SimConnect_Open(&hSimConnect, "CommBus client", NULL, 0, 0, 0));
// Setup
while (1)
{
SimConnect_CallDispatch(hSimConnect, MyDispatchProcSO, NULL);
Sleep(1);
}
return 0;
}
Declare an event enum:
enum EVENTS
{
CommBusEvent,
}
Subscribe to a CommBus event by calling SimConnect_SubscribeToCommBusEvent (in the above code this can be added at the //Setup comment):
SimConnect_SubscribeToCommBusEvent(hSimConnect, EVENTS::CommBusEvent, "MyCommBusEvent");
In the DispatchProc process the event:
std::string str;
void CALLBACK MyDispatchProcSO(SIMCONNECT_RECV* pData, DWORD cbData, void* pContext)
{
switch (pData->dwID)
{
case SIMCONNECT_RECV_ID_COMM_BUS: // The received data comes from a comm bus event
{
SIMCONNECT_RECV_COMM_BUS* pCommBusEvt = (SIMCONNECT_RECV_COMM_BUS*)pData;
switch (pCommBusEvt->uEventID) // Check which event this is
{
case EVENT_COMM_BUS:
{
if (pCommBusEvt->dwOutOf == 1)
{
PrintReceivedData(pCommBusEvt->rgData);
}
else
{
receptionBuffer += data.rgData;
if (pCommBusEvt->dwEntryNumber + 1 == pCommBusEvt->dwOutOf)
{
PrintReceivedData(receptionBuffer);
receptionBuffer = "";
}
}
break;
}
}
}
}
}
Finally, in the WASM module you would call the event:
fsCommBusCall("MyCommBusEvent", "{value : 42}", bufferSize, FsCallFlags::FsCall_SimConnect)
In your SimConnect (C#), open a connection:
SimConnect m_oSimConnect = new SimConnect("Connection name", m_hWnd, WM_USER_SIMCONNECT, null, 0);
Create a CommBus callback:
string receptionBuffer;
void OnCommBusEvent(SimConnect sender, SIMCONNECT_RECV_COMM_BUS data)
{
switch (data.uEventID)
{
case ((int)Events.CommBusEvent):
{
if (data.dwOutOf == 1)
{
PrintReceivedData(data.rgData);
}
else
{
receptionBuffer += data.rgData;
if (data.dwEntryNumber + 1 == data.dwOutOf)
{
PrintReceivedData(receptionBuffer);
receptionBuffer = "";
}
}
}
break;
default:
break;
}
}
Register a callback on Recv CommBus:
m_oSimConnect.OnRecvCommBus += new SimConnect.RecvCommBusEventHandler(OnCommBusEvent);
Register the event:
m_oSimConnect.SubscribeToCommBusEvent(Events.CommBusEvent, "SimConnectEventName");
Finally, in the WASM module you would call the event:
void* ctx = something;
fsCommBusRegister("SimConnectEventName", MyWasmCallback, ctx);
Related Topics