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);

 

 

0/255