COMMUNICATION API
The functions here are designed to enable cross-module communication, whether it is between two WASM modules, or a WASM and a JS module. When using this API it's worth noting the following:
- JSON is a good way to format data for communication between WASM and JS. 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 between WASM and JS.
- 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, including even WASM to WASM.
You can find a sample project to use as a reference when using the Communication API here:
Typedefs
When using the functions listed below, 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
)
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:
Function | Description | Type |
---|---|---|
FsCommBusBroadcastFlags |
This enum is used to specified the type of module/gauge to broadcast an event call to. | Enum |
Call Js From Wasm
To use the API to call a JS function from a WASM module you would need to do the following:
- In your JS file you need to create the callback:
myJsCallback(args) { ... }
- You then need to register the view listener:
this.wasmListener = RegisterViewListener('JS_LISTENER_COMM_BUS');
- Next you would connect the callback to an event name:
this.wasmListener.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 WASM
To use the API to call a WASM function from a WASM module you would need to do one of the following:
- First, create the callback in the first WASM module:
Then register the callback as well:static void MyWasmCallback(const char* args, unsigned int size, void* ctx) { ... }
It is possible to add a pointer to a context. This pointer will be retrieved in the callback in thefsCommBusRegister("MyWasmCallback", MyWasmCallback);
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 WASM From JS
To use the API to call a WASM function from a JS module you would need to do the following:
- In the WASM module you would create you callback:
static void MyWasmCallback(const char* args, unsigned int size, void *ctx) { ... }
- Then you would register the callback:
It is possible to add a pointer to a context. This pointer will be retrieved in the callback in thefsCommBusRegister("MyWasmCallback", MyWasmCallback);
ctx
argument:void* ctx = something; fsCommBusRegister("MyWasmCallback", MyWasmCallback, ctx);
- Next, you need to register the listener in the JavaScript:
this.wasmListener = RegisterViewListener('JS_LISTENER_COMM_BUS');
- Then call the WASM event using either of the following:
orCoherent.call("COMM_BUS_WASM_CALLBACK", "MyWasmCallback", "{value : 42}");
this.wasmListener.call("COMM_BUS_WASM_CALLBACK", "MyWasmCallback", "{value : 42}");
Known Issues
When the simulation is paused, WASM is still updated. However this is not the case for JS guages. This means that events sent to JS from a WASM module 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 int he queue. It is the responsibility of the developer to handle this gracefully and try and prevent a build up of events when paused.