This sample demonstrates the communication between C++ and JavaScript
- transferring data
- executing C++ from JavaScript and JavaScript from C++
- Note
- Supplied code is not representative for a well-designed, high-performance solution. It's written for simplicity and its purpose is to demonstrate features of Coherent UI.
Building the sample
The sample solution is already configured and you only have to compile and run it.
It uses a sample mini game framework that provides very basic functionality.
The output will be in the Coherent/Samples/UI/bin directory.
Prerequisites
This sample builds upon the Input in 2D sample and assumes that you understand it.
For a more detailed explanation of how binding works, you can check the Detailed Binding Guide
Key points
Coherent::UI::ViewListener::OnBindingsReady
is overridden to allow registration of C++ handlers to be called from JavaScript.
- The debugger port is set inside the
Coherent::UI::ContextSettings
to allow easier development and troubleshooting.
- A simple C++ structure is exposed to Coherent UI so it can be transferred between C++ and JavaScript
Sample walkthrough
Initialize the context factory, then create a view context, enabling support for cookies.
Coherent::UI::ViewContextFactory* contextFactory = InitializeCoherentUI(
COHERENT_UI_SDK_VER, COHERENT_KEY, renderingParams, factorySettings);
if (!contextFactory)
{
return 3;
}
= contextFactory->CreateViewContext(ctxSettings, &listener);
When the view is ready for the registration of C++ call and event handlers Coherent::UI::ViewListener::OnReadyForBindings
is called
virtual void OnReadyForBindings(int frameId, const wchar_t* path, bool isMainFrame) override
{
if(!isMainFrame)
{
return;
}
m_View->BindCall("ApplyOptions", Coherent::UI::MakeHandler(&g_OptionsHandler, &OptionsHandler::ApplyOptions));
m_View->BindCall("GetLatency", Coherent::UI::MakeHandler(&GetNetworkLatency));
m_View->BindCall("GetGameTime", Coherent::UI::MakeHandler(&GetGameTime));
m_View->RegisterForEvent("ViewReady", Coherent::UI::MakeHandler(this, &ViewEventListener::ViewReady));
}
The HTML and Javascript code for this sample is in Coherent/Samples/UI/bin/html/binding.html.
When the document has been loaded and C++ handlers have been registered the Ready
event is fired.
engine.on('Ready', function () {
engine.trigger('ViewReady');
});
This actually triggers
void ViewReady()
{
m_View->TriggerEvent("OpenOptions", m_Options);
}
Because the Options
structure is exposed to Coherent UI it may be transferred between C++ and JavaScript.
{
if(
auto type = binder->
RegisterType(
"GameOptions", options))
{
type.Property("Backend", &Options::Backend)
.Property("Width", &Options::Width)
.Property("Height", &Options::Height)
.PropertyReadOnly("Username", &Options::GetUserName)
.Property("NetworkPort", &Options::GetNetPort, &Options::SetNetPort);
}
}
JavaScript functions bound to event "OptionOptions"
receive an JavaScript object with the described properties and values taken from the C++ options object given to Coherent::UI::View::TriggerEvent
.
function openOptions(options) {
$("#options").dialog( "open" );
$("#backend").text(options.Backend);
$("#gameWidth").val(options.Width);
$("#gameHeight").val(options.Height);
$("#user").text(options.Username);
$("#netPort").val(options.NetworkPort);
}
engine.on("OpenOptions", openOptions);
If JavaScript calls C++ function that takes an Options
as an argument, the JavaScript object must have a property __Type
with the registered name for the Options
structure - GameOptions
function onApplyButton(){
var options = {};
options.__Type = "GameOptions";
options.Backend = $("#backend").text();
options.Width = Number($("#gameWidth").val());
options.Height = Number($("#gameHeight").val());
options.Username = $("#user").text();
options.NetworkPort = Number($("#netPort").val());
engine.call("ApplyOptions", options);
}