-
Notifications
You must be signed in to change notification settings - Fork 5
GUI Overview
This is a work in progress.
FimbulwinterClient GUI is based on Awesomium, a hacked source of Chromium which is the base of the Google Chrome browser. So yes, the GUI is pure HTML5, CSS3 and JavaScript.
In this documentation, the server is the C++ logic and the client is the JavaScript logic.
Like in Chromium, all scripting and rendering logic is done in another process to prevent the GUI to crash the whole game and to provide premium load balancing between CPUs.
Our GUI uses RocketMVVM, a Model-View-ViewModel implementation created specifically to FimbulwinterClient. In this case the controller and the model is written in C++ and the View and the ViewModel in HTML and JavaScript.
Windows are created using jQuery UI dialog, refer to jQuery UI documentation for more information.
RocketMVVM has two basic concepts: observable values and computed values. Observable values are ordinary variables that when changed fires an event notifying the change. Computed values are functions that consumes one or more values from the current ViewModel, it value is computed each time that some of their dependencies notifies that was changed.
The core of RocketMVVM is the ViewModel object.
ModelView constructor takes one argument describing it fields.
var exampleViewModel = new mvvm.ViewModel(function() {
this.name = mvvm.observable('');
this.level = mvvm.observable(0);
this.description = mvvm.computed(function() {
return this.name() + ', level ' + this.level() + '.';
}, this, ['name', 'level']);
this.select: function() {
alert('You choose ' + this.description() + '.');
}
});
The ViewModel object has the applyBindings function.
$(function() {
$("#testWindow").dialog();
exampleViewModel.applyBindings($("#testWindow"));
});
<div id="testWindow">
<p>Name: <span data-bind="text: name" /></p>
<p>Level: <span data-bind="text: level" /></p>
<p>Description: <span data-bind="text: description" /></p>
<form>
<p><input data-bind="value: name" /></p>
<p><input data-bind="value: level" /></p>
<p><button data-bind="click: select">Select</button></p>
</form>
</div>
To update ViewModel data, you use the update function.
exampleViewModel.update({ name: 'John Doe', level: 33 });
This is the most common case, first we need to create a server-side ViewModel matching the client-side one.
#include <Ragnarok/Gui/RocketMVVM.h>
class TestViewModel : public RocketMVVM::ViewModel
{
public:
MVVM_FIELD_STR(Name, "name");
MVVM_FIELD(Level, "level", int);
}
Then we need to register a function on a global object that will receive the client-side ViewModel instance.
static TestViewModel TestModel;
void RegisterObjects()
{
GuiManager *gui = GuiManager::Instance();
JSObject globalObject = gui->View()->CreateGlobalJavascriptObject("Application.Test").ToObject();
gui->Dispatcher()->BindAsync(globalObject, "SetTestProxy", JSDispatcher::AsyncFunction([&] (const JSArray &args) {
TestModel.SetProxy(args[0].ToObject());
}));
}
Then you use TestViewModel::SetX and ViewModel::Update functions.
void UpdateData()
{
TestModel.SetName("John Doe");
TestModel.SetLevel(33);
TestModel.Update();
}
To bind a client-side ViewMode to the server-side one, you call:
Application.Test.SetTestProxy(exampleViewModel);