COMMUNICATION API

The following JavaScript functions are used for for communicating data between various SimConnect clients, WebAssembly modules, and JavaScript gauges. You can find information on the other platform communication functions from the following pages:

  

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 functions and methods listed below are available by including the CommBus.js file:

Include.addScript("/JS/Services/CommBus.js");

 

 

RegisterCommBusListener

This function is used to register the communication (CommBus) event listener.

function RegisterCommBusListener(callback?: any): CommBusListener;

 

Parameter Description
callback An optional callback called when the listener has been registered.

 

Return

A CommBusListener object.

 

 

CommBusListener::callWasm

This function is used to call a communication (CommBus) event on WASM modules.

CommBusListener::callWasm(name: string, jsonBuf: string): Promise<any>;

 

Parameter Description
name The name of the event to call.
jsonBuf A buffer of data sent along side the event. Formatting the buffer as JSON is a good way to send data, but it is not mandatory.

 

Return

A promise about the completion of the call operation.

 

 

CommBusListener::callSimConnect

This function is used to call a communication (CommBus) event on SimConnect clients.

CommBusListener::callSimConnect(name: string, jsonBuf: string): Promise<any>;

 

Parameter Description
name The name of the event to call.
jsonBuf A buffer of data sent along side the event. Formatting the buffer as JSON is a good way to send data, but it is not mandatory.

 

Return

A promise about the completion of the call operation.

 

 

CommBusListener::callAll

This function is used to call a communication (CommBus) event on both WASM modules and SimConnect clients.

CommBusListener::callAll(name: string, jsonBuf: string): Promise<any>;

 

Parameter Description
name The name of the event to call.
jsonBuf A buffer of data sent along side the event. Formatting the buffer as JSON is a good way to send data, but it is not mandatory.

 

Return

A promise about the completion of the call operation.

 

 

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 Using JavaScript

Create a JS callback:

myJsCallback(args) { ... }

 

Register the view listener:

this.wasmListener = RegisterCommBusListener();

 

Register the callback on the event:

this.wasmListener.on("MyJsCallback", this.myJsCallback);

 

 

Call A WASM Event From JSCall A WASM Event From JS

In the WASM module you would create your callback:

static void MyWasmCallback(const char* args, unsigned int size, void* ctx) { ... }


Then you would register the callback:

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


Register your listener in the JavaScript:

this.commBusListener = RegisterCommBusListener();


Then call the WASM event using either of the following in the JS methods:

// Using the communications API
this.commBusListener.callWasm("MyWasmCallback", "{value : 42}");
 
// Using Coherent
Coherent.call("COMM_BUS_WASM_CALLBACK", "MyWasmCallback", "{value : 42}");
this.wasmListener.call("COMM_BUS_WASM_CALLBACK", "MyWasmCallback", "{value : 42}");


 

Call A SimConnect (C++ / C#) Event From JSCall A SimConnect (C++ / C#) Event From JS

In 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;
                }
            }
        }
    }
}

 

Register your listener in the JavaScript:

this.commBusListener = RegisterCommBusListener();

 

Then call the SimConnect event using the following in the JS file:

this.commBusListener.callSimConnect("MyCommBusEvent", "{value : 42}");

 

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

 

Register your listener in the JavaScript:

this.commBusListener = RegisterCommBusListener();

 

Then call the SimConnect (C#) event using the following in the JS file:

this.commBusListener.callSimConnect("SimConnectEventName", "{value : 42}");

 

 

 

Known Issues

When the simulation is paused, WebAssembly modules and SimConnect clients are still updated. However this is not the case for JavaScript gauges. Therefore, events sent to JS from WASM/SimConnect will be queued but not processed until the simulation is unpaused. When the simulation is unpaused all queued events will be processed in the order that they were received, which may lead to a freeze if there are multiple events in the queue. It is the responsibility of the developer to handle this gracefully and try and prevent a build up of events when paused.

 

0/255