SlideShare a Scribd company logo
1 of 43
www.italiancpp.org
C++ Day 2017
2 Dicembre, Modena
C++ and UIs
an unorthodox approach
Daniele Pallastrelli
C++ Day 2017 – Un evento dell’Italian C++ Community
C++ today
- Games
- Embedded
- OS, VM &c
- Simulations & HPC
- …
In general:
- High Performance / low latency applications
- Hardware interaction
- Legacy code
C++ Day 2017 – Un evento dell’Italian C++ Community
How do we usually write UIs for C++?
- Native APIs (Win API, Xlib, Cocoa)
- Class Frameworks (MFC, WTL, .NET, …)
- Widget cross-platform frameworks (FLTK, …)
- Huge cross-platform frameworks
(Qt/copperspice, wxWidgets, GTK+, Ultimate++ , …)
- Modern C++ focused on UIs (Nana C++, …)
C++ Day 2017 – Un evento dell’Italian C++ Community
How do we usually write UIs for C++?
- Native APIs (Win API, Xlib, Cocoa)
- Class Frameworks (MFC, WTL, .NET, …)
- Widget cross-platform frameworks (FLTK, …)
- Huge cross-platform frameworks
(Qt/copperspice, wxWidgets, GTK+, Ultimate++ , …)
- Modern C++ focused on UIs (Nana C++, …)
C++ Day 2017 – Un evento dell’Italian C++ Community
Maybe…
C++ Day 2017 – Un evento dell’Italian C++ Community
An alternative approach
C++ Day 2017 – Un evento dell’Italian C++ Community
Why html?
Better design
Graphic designers are used to html and css
Sharp division between layout and content (more or less…)
Lots of material and documentation
C++ Day 2017 – Un evento dell’Italian C++ Community
Lots of material and documentation
C++ Day 2017 – Un evento dell’Italian C++ Community
Not a silver bullet
It's not for all the applications
Just a solution I used many times in different circumstances
C++ Day 2017 – Un evento dell’Italian C++ Community
Previous attempts
Http (long polling) -> requires web server
Chrome extensions
Qt WebEngine
Electron / CEF (Chromium Embedded Framework)
C++ Day 2017 – Un evento dell’Italian C++ Community
Html5, finally!
Better graphics, multimedia, offline,
storage, …
Above all:
Now we can load a local page interacting with
a native application through WebSockets
C++ Day 2017 – Un evento dell’Italian C++ Community
Websocket
WebSocket is a computer communications protocol,
providing full-duplex communication channels over a
single TCP connection.
The WebSocket protocol enables interaction between a
browser and a web server with lower overheads, facilitating
real-time data transfer from and to the server. This is made
possible by providing a standardized way for the server to
send content to the browser without being solicited by the
client, and allowing for messages to be passed back and forth
while keeping the connection open. In this way, a two-way
(bi-directional) ongoing conversation can take place between
a browser and the server.
C++ Day 2017 – Un evento dell’Italian C++ Community
Websocket
WebSocket is a computer communications protocol,
providing full-duplex communication channels over a
single TCP connection.
The WebSocket protocol enables interaction between a
browser and a web server with lower overheads, facilitating
real-time data transfer from and to the server. This is made
possible by providing a standardized way for the server to
send content to the browser without being solicited by the
client, and allowing for messages to be passed back and forth
while keeping the connection open. In this way, a two-way
(bi-directional) ongoing conversation can take place between
a browser and the server.
C++ Day 2017 – Un evento dell’Italian C++ Community
Websocket
WebSocket is a computer communications protocol,
providing full-duplex communication channels over a
single TCP connection.
The WebSocket protocol enables interaction between a
browser and a web server with lower overheads, facilitating
real-time data transfer from and to the server. This is made
possible by providing a standardized way for the server to
send content to the browser without being solicited by the
client, and allowing for messages to be passed back and forth
while keeping the connection open. In this way, a two-way
(bi-directional) ongoing conversation can take place between
a browser and the server.
C++ Day 2017 – Un evento dell’Italian C++ Community
Websocket
WebSocket is a computer communications protocol,
providing full-duplex communication channels over a
single TCP connection.
The WebSocket protocol enables interaction between a
browser and a web server with lower overheads, facilitating
real-time data transfer from and to the server. This is made
possible by providing a standardized way for the server to
send content to the browser without being solicited by the
client, and allowing for messages to be passed back and forth
while keeping the connection open. In this way, a two-way
(bi-directional) ongoing conversation can take place between
a browser and the server.
C++ Day 2017 – Un evento dell’Italian C++ Community
websocket advantage #1
Browsers don't enforce the Same Origin Policy (and its CORS
relaxation) for WebSockets as opposed to AJAX calls (*)
=> no webserver needed
(*) still, a websocket server can restrict access by checking
"origin"
C++ Day 2017 – Un evento dell’Italian C++ Community
websocket advantage #2
Provides a standardized way for the server to send content
to the browser without being solicited by the client.
The WebSocket protocol enables interaction between a
browser and a web server with lower overheads, facilitating
real-time data transfer from and to the server.
=> Solves the problem of pushing events to the client
C++ Day 2017 – Un evento dell’Italian C++ Community
#1: bring in websockets
Client (javascript): overly simple
var ws = new WebSocket( 'ws://localhost:9971' );
ws.onmessage = function(msg) { console.log(msg); }
ws.onopen = function () { console.log( 'WS connected' ); }
ws.onclose = function () { console.log( 'WS closed' ); }
ws.onerror = function () { console.log( 'WS error' ); }
…
if (ws.readyState == ws.OPEN) ws.send( 'hello world!' );
C++ Day 2017 – Un evento dell’Italian C++ Community
#1: bring in websockets
Server (C++): websocket library
boost::beast
- asynchronous (foster single thread)
- boost::asio paradigm (proactor and reactor)
- coming to Boost 1.66.0
- interface a little too much error-prone for my taste 
C++ Day 2017 – Un evento dell’Italian C++ Community
#2: choose a data serialization format
Json is the format with less friction for Javascript
var obj = {
foo: 'foo string',
bar: 42
};
var jsonString = JSON.stringify( obj ); // serialize
var jsonObj = JSON.parse( jsonString ); // deserialize
assert( jsonObj.foo === 'foo string' );
assert( jsonObj.bar === 42 );
C++ Day 2017 – Un evento dell’Italian C++ Community
#2: choose a data serialization format
On the C++ side: libraries to convert data <-> JSON
(e.g., nlohmann json)
// create object from string literal
json j = "{ "happy": true, "pi": 3.141 }"_json;
// or even nicer with a raw string literal
auto j2 = R"(
{
"happy": true,
"pi": 3.141
}
)"_json;
// explicit conversion to string
std::string s = j.dump(); // {"happy":true,"pi":3.141}
json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {
{"everything", 42}
}},
{"list", {1, 0, 2}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}}
};
C++ Day 2017 – Un evento dell’Italian C++ Community
Choices, as usual
We need to decide which part goes into the C++ component
and which into the Javascript client
C++ Day 2017 – Un evento dell’Italian C++ Community
Not so bad…
We're forced to do something we usually don't do with
classes inside the same component:
Carefully design the interface
between the two components.
C++ Day 2017 – Un evento dell’Italian C++ Community
First try: Dumb Client
The protocol objects are the html graphical widgets
Events (js -> C++): "button X has been pressed"
Commands (C++ -> js): "set the text of label Y to Z"
Javascript client is a dumb proxy
C++ Day 2017 – Un evento dell’Italian C++ Community
Packaging…
We want the usual desktop application behaviour.
=> just add a script that launches the .exe and then the
browser
… with a server shutdown when the connection is lost.
REM file softphone.cmd
@echo off
cd content
start "" ui_websocket.exe
start "" index.htm
exit
C++ Day 2017 – Un evento dell’Italian C++ Community
C++ side Javascript side
void OnIncomingCall()
{
using json = nlohmann::json;
json msg = {
{ "id", "statuslabel" }
{ "request", "setlabel" },
{ "value", "Incoming" }
};
webSocket.Send( msg.dump() );
}
webSocket.onmessage = function (event) {
var jsonObj = JSON.parse(event.data);
var item =
document.getElementById(jsonObj.id);
switch (jsonObj.request) {
case "setlabel":
item.innerHTML = jsonObj.value;
break;
case "setprogressbar":
item.style.width = jsonObj.value;
break;
…
}
};
C++ Day 2017 – Un evento dell’Italian C++ Community
Javascript side C++ side
function onCallClick() {
var ev = {
event: 'onclick',
source: 'callbtn'
};
webSocket.send( JSON.stringify(ev) );
}
function onHangupClick() {
var ev = {
event: 'onclick',
source: 'hangupbtn'
};
webSocket.send( JSON.stringify(ev) );
}
webSocket.OnMessage( [&](const string& msg){
using json = nlohmann::json;
auto jsonObj = json::parse(msg);
auto source = jsonObj.at("source");
auto event = jsonObj.at("event");
auto handler =
handlers.find( make_pair(source, event) );
if (handler != handlers.end()) handler->second();
} );
C++ Day 2017 – Un evento dell’Italian C++ Community
Improvement #1
webSocket.onmessage = function (event) {
eval( event.data );
};
void OnIncomingCall()
{
webSocket.Send("document.getElementById('statuslabel').innerHTML='Incoming'");
}
C++ Day 2017 – Un evento dell’Italian C++ Community
Improvement #2
$(function () {
// all the buttons
var buttons =
document.getElementsByTagName('button');
for (var i = 0; i < buttons.length; i++) {
var button = buttons[i];
button.onclick = function () {
const ev = {
event: 'onclick',
id: this.id
};
webSocket.send( JSON.stringify(ev) );
};
}
// same for inputs etc.
}
webSocket.OnMessage( [&](const string& msg){
using json = nlohmann::json;
auto jsonObj = json::parse(msg);
auto source = jsonObj.at("source");
auto event = jsonObj.at("event");
auto handler =
handlers.find( make_pair(source, event) );
if (handler != handlers.end()) handler->second();
} );
C++ Day 2017 – Un evento dell’Italian C++ Community
Can you spot the asimmetry?
It seems like we can register javascript callbacks to C++
events
But not the other way around!
The asimmetry is due to languages differences:
Javascript eval can exec an arbitrary string
C++ Day 2017 – Un evento dell’Italian C++ Community
Are we done, then?
… not really.
All the work is done by C++ (even input validation!)
It's far better if the protocol speaks in terms of domain (e.g.,
phone call, ringtone, speaker, microphone,…):
- input validation in javascript
- better separation between app logic and UI
- app logic independent from the UI representation
C++ Day 2017 – Un evento dell’Italian C++ Community
An higher level protocol…
Direction: UI javascript -> C++ Application
{
"request": "connection",
"data": {
"server": "127.0.0.1",
"user": "daniele",
"password": "123456"
}
}
{
"request": "call",
"data": {
"number": "338123456"
}
}
Direction: C++ Application -> UI javascript
{
"event": "levelschanged",
"data": {
"miclevel": 32,
"speakerlevel": 73
}
}
{
"event": "regstatuschanged",
"data": {
"status": "unregistered"
}
}
C++ Day 2017 – Un evento dell’Italian C++ Community
Too much code to write?
// QT code for event handling
void Ui::AutoanswerActive(bool active)
{
softPhone.Autoanswer(active));
}
connect(autoanswerCheckBox, SIGNAL(clicked(bool)), this, SLOT(AutoanswerActive(bool)));
// equivalent code
handlers["autoanswer"] = [&](json event){
bool active = event.at("active");
softPhone.Autoanswer(active);
});
C++ Day 2017 – Un evento dell’Italian C++ Community
Too much code to write?
using json = nlohmann::json;
std::unordered_map<std::string, std::function<void(json)>> handlers;
webSocket.OnMessage( [&](const string& msg){
auto jsonObj = json::parse(msg);
auto event = jsonObj.at("event");
auto handler = handlers.find( event) );
if (handler != handlers.end()) handler->second(jsonObj);
} );
C++ Day 2017 – Un evento dell’Italian C++ Community
"…but javascript sucks!"
… you can even use C++ inside the browser!
C++ Day 2017 – Un evento dell’Italian C++ Community
Emscripten
emcc is a LLVM back end that produces asm.js
C++ Day 2017 – Un evento dell’Italian C++ Community
asm.js
function Vb(d) {
d = d | 0;
var e = 0, f = 0, h = 0, j = 0, k = 0, l = 0,
m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0;
e = i;
i = i + 12 | 0;
f = e | 0;
h = d + 12 | 0;
j = c[h >> 2] | 0;
if ((j | 0) > 0) {
c[h >> 2] = 0;
k = 0
} else {
k = j
}
j = d + 24 | 0;
if ((c[j >> 2] | 0) > 0) {
c[j >> 2] = 0
}
...
}
Intermediate programming
language intended to
simulate Assembler.
It's a small subset of
JavaScript optimized for
performances.
Runs everywhere, but all
the four major browsers
optimize for asm.js
C++ Day 2017 – Un evento dell’Italian C++ Community
Emscripten APIs supported
C++ standard libraries which don’t need to interact with the
system
- Network support (libc-style, non-blocking only(!))
- File system access
- Graphics (OpenGL ES)
- Audio, keyboard, mouse, joystick (SDL)
- Integration with HTML5
C++ Day 2017 – Un evento dell’Italian C++ Community
Emscripten usage
•Game Engines(!)
• UE3 (reported to be ported in 4 days)
• UE4
• Unity (C# to C++ with IL2CPP and C++ to asm.js with Emscripten)
•Games
• Quake 3
• Doom
• OpenDune
•Libraries/Frameworks
• OpenSSL
• SQLite
• Pepper (via pepper.js)
• Quite a few of Qt demos
C++ Day 2017 – Un evento dell’Italian C++ Community
Emscripten usage
•Game Engines(!)
• UE3 (reported to be ported in 4 days)
• UE4
• Unity (C# to C++ with IL2CPP and C++ to asm.js with Emscripten)
•Games
• Quake 3
• Doom
• OpenDune
•Libraries/Frameworks
• OpenSSL
• SQLite
• Pepper (via pepper.js)
• Quite a few of Qt demos
C++ Day 2017 – Un evento dell’Italian C++ Community
Does it make sense?
We have different materials, like statically typed and
dynamically typed languages, yet we don't have a sound
theory of forces, so we end up with the usual evangelist
trying to convert the world to its material of choice.
It's kinda funny, because it's just as sensible as having a
Brick Evangelist trying to convince you to use bricks instead
of glass for your windows ("it's more robust!"), and a Glass
Evangelist trying to convince you to build your entire house
out of glass ("you'll get more light!").
Carlo Pescio
C++ Day 2017 – Un evento dell’Italian C++ Community
Let's recap
A "one size fits all" approach never works
It's just a new way you can take into account:
- Crossplatform (as much as the C++ you write)
- No constraint on your C++ code (no hugly macros, no custom compilers, …)
- Sharp separation between UI and app logic
- Multiple skins
- Automatic test of the whole application (plugging a test websocket client)
- You can use the whole toolset available for JS (people included)
- Idea useful also in other languages (see scripting languages)
But – please – split the application the right way!
C++ Day 2017 – Un evento dell’Italian C++ Community
References
i=43
Me: @DPallastrelli
Me: it.linkedin.com/in/pallad
Github: http://github.com/daniele77

More Related Content

Similar to C++ and UIs: an unorthodox approach

Programming IoT Gateways with macchina.io
Programming IoT Gateways with macchina.ioProgramming IoT Gateways with macchina.io
Programming IoT Gateways with macchina.ioGünter Obiltschnig
 
Pushing the Boundaries of Sencha and HTML5′s WebRTC
Pushing the Boundaries of Sencha and HTML5′s WebRTCPushing the Boundaries of Sencha and HTML5′s WebRTC
Pushing the Boundaries of Sencha and HTML5′s WebRTCRich Waters
 
Cytoscape and the Web
Cytoscape and the WebCytoscape and the Web
Cytoscape and the WebKeiichiro Ono
 
C++ interoperability with other languages
C++ interoperability with other languagesC++ interoperability with other languages
C++ interoperability with other languagesAlberto Bignotti
 
Add the power of the Web to your embedded devices with WPE WebKit
Add the power of the Web to your embedded devices with WPE WebKitAdd the power of the Web to your embedded devices with WPE WebKit
Add the power of the Web to your embedded devices with WPE WebKitIgalia
 
Front-end. Global domination
Front-end. Global dominationFront-end. Global domination
Front-end. Global dominationStfalcon Meetups
 
JS digest. Mid-Summer 2017
JS digest. Mid-Summer 2017JS digest. Mid-Summer 2017
JS digest. Mid-Summer 2017ElifTech
 
C++ Windows Forms L01 - Intro
C++ Windows Forms L01 - IntroC++ Windows Forms L01 - Intro
C++ Windows Forms L01 - IntroMohammad Shaker
 
Easing offline web application development with GWT
Easing offline web application development with GWTEasing offline web application development with GWT
Easing offline web application development with GWTArnaud Tournier
 
20160201_resume_Vladimir_Chesnokov
20160201_resume_Vladimir_Chesnokov20160201_resume_Vladimir_Chesnokov
20160201_resume_Vladimir_ChesnokovVladimir Chesnokov
 
MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0
MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0
MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0Thomas Conté
 
Native client
Native clientNative client
Native clientzyc901016
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsShahed Chowdhuri
 
Programming IoT Gateways in JavaScript with macchina.io
Programming IoT Gateways in JavaScript with macchina.ioProgramming IoT Gateways in JavaScript with macchina.io
Programming IoT Gateways in JavaScript with macchina.ioGünter Obiltschnig
 
WebRTC ... GWT & in-browser computation
WebRTC ... GWT & in-browser computationWebRTC ... GWT & in-browser computation
WebRTC ... GWT & in-browser computationJooinK
 
The WebKit project (LinuxCon North America 2012)
The WebKit project (LinuxCon North America 2012)The WebKit project (LinuxCon North America 2012)
The WebKit project (LinuxCon North America 2012)Igalia
 

Similar to C++ and UIs: an unorthodox approach (20)

Programming IoT Gateways with macchina.io
Programming IoT Gateways with macchina.ioProgramming IoT Gateways with macchina.io
Programming IoT Gateways with macchina.io
 
Pushing the Boundaries of Sencha and HTML5′s WebRTC
Pushing the Boundaries of Sencha and HTML5′s WebRTCPushing the Boundaries of Sencha and HTML5′s WebRTC
Pushing the Boundaries of Sencha and HTML5′s WebRTC
 
Cytoscape and the Web
Cytoscape and the WebCytoscape and the Web
Cytoscape and the Web
 
how u can learn C/C++
how u can learn C/C++ how u can learn C/C++
how u can learn C/C++
 
C++ interoperability with other languages
C++ interoperability with other languagesC++ interoperability with other languages
C++ interoperability with other languages
 
Add the power of the Web to your embedded devices with WPE WebKit
Add the power of the Web to your embedded devices with WPE WebKitAdd the power of the Web to your embedded devices with WPE WebKit
Add the power of the Web to your embedded devices with WPE WebKit
 
Front-end. Global domination
Front-end. Global dominationFront-end. Global domination
Front-end. Global domination
 
Frontend. Global domination.
Frontend. Global domination.Frontend. Global domination.
Frontend. Global domination.
 
Encode Club Hackathon
Encode Club Hackathon  Encode Club Hackathon
Encode Club Hackathon
 
JS digest. Mid-Summer 2017
JS digest. Mid-Summer 2017JS digest. Mid-Summer 2017
JS digest. Mid-Summer 2017
 
C++ Windows Forms L01 - Intro
C++ Windows Forms L01 - IntroC++ Windows Forms L01 - Intro
C++ Windows Forms L01 - Intro
 
Easing offline web application development with GWT
Easing offline web application development with GWTEasing offline web application development with GWT
Easing offline web application development with GWT
 
20160201_resume_Vladimir_Chesnokov
20160201_resume_Vladimir_Chesnokov20160201_resume_Vladimir_Chesnokov
20160201_resume_Vladimir_Chesnokov
 
MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0
MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0
MS Day EPITA 2010: Visual Studio 2010 et Framework .NET 4.0
 
As Pdotnet
As PdotnetAs Pdotnet
As Pdotnet
 
Native client
Native clientNative client
Native client
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web Apps
 
Programming IoT Gateways in JavaScript with macchina.io
Programming IoT Gateways in JavaScript with macchina.ioProgramming IoT Gateways in JavaScript with macchina.io
Programming IoT Gateways in JavaScript with macchina.io
 
WebRTC ... GWT & in-browser computation
WebRTC ... GWT & in-browser computationWebRTC ... GWT & in-browser computation
WebRTC ... GWT & in-browser computation
 
The WebKit project (LinuxCon North America 2012)
The WebKit project (LinuxCon North America 2012)The WebKit project (LinuxCon North America 2012)
The WebKit project (LinuxCon North America 2012)
 

Recently uploaded

How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension AidPhilip Schwarz
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024Mind IT Systems
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfryanfarris8
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionOnePlan Solutions
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 

Recently uploaded (20)

How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdfAzure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
Azure_Native_Qumulo_High_Performance_Compute_Benchmarks.pdf
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 

C++ and UIs: an unorthodox approach

  • 1. www.italiancpp.org C++ Day 2017 2 Dicembre, Modena C++ and UIs an unorthodox approach Daniele Pallastrelli
  • 2. C++ Day 2017 – Un evento dell’Italian C++ Community C++ today - Games - Embedded - OS, VM &c - Simulations & HPC - … In general: - High Performance / low latency applications - Hardware interaction - Legacy code
  • 3. C++ Day 2017 – Un evento dell’Italian C++ Community How do we usually write UIs for C++? - Native APIs (Win API, Xlib, Cocoa) - Class Frameworks (MFC, WTL, .NET, …) - Widget cross-platform frameworks (FLTK, …) - Huge cross-platform frameworks (Qt/copperspice, wxWidgets, GTK+, Ultimate++ , …) - Modern C++ focused on UIs (Nana C++, …)
  • 4. C++ Day 2017 – Un evento dell’Italian C++ Community How do we usually write UIs for C++? - Native APIs (Win API, Xlib, Cocoa) - Class Frameworks (MFC, WTL, .NET, …) - Widget cross-platform frameworks (FLTK, …) - Huge cross-platform frameworks (Qt/copperspice, wxWidgets, GTK+, Ultimate++ , …) - Modern C++ focused on UIs (Nana C++, …)
  • 5. C++ Day 2017 – Un evento dell’Italian C++ Community Maybe…
  • 6. C++ Day 2017 – Un evento dell’Italian C++ Community An alternative approach
  • 7. C++ Day 2017 – Un evento dell’Italian C++ Community Why html? Better design Graphic designers are used to html and css Sharp division between layout and content (more or less…) Lots of material and documentation
  • 8. C++ Day 2017 – Un evento dell’Italian C++ Community Lots of material and documentation
  • 9. C++ Day 2017 – Un evento dell’Italian C++ Community Not a silver bullet It's not for all the applications Just a solution I used many times in different circumstances
  • 10. C++ Day 2017 – Un evento dell’Italian C++ Community Previous attempts Http (long polling) -> requires web server Chrome extensions Qt WebEngine Electron / CEF (Chromium Embedded Framework)
  • 11. C++ Day 2017 – Un evento dell’Italian C++ Community Html5, finally! Better graphics, multimedia, offline, storage, … Above all: Now we can load a local page interacting with a native application through WebSockets
  • 12. C++ Day 2017 – Un evento dell’Italian C++ Community Websocket WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection. The WebSocket protocol enables interaction between a browser and a web server with lower overheads, facilitating real-time data transfer from and to the server. This is made possible by providing a standardized way for the server to send content to the browser without being solicited by the client, and allowing for messages to be passed back and forth while keeping the connection open. In this way, a two-way (bi-directional) ongoing conversation can take place between a browser and the server.
  • 13. C++ Day 2017 – Un evento dell’Italian C++ Community Websocket WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection. The WebSocket protocol enables interaction between a browser and a web server with lower overheads, facilitating real-time data transfer from and to the server. This is made possible by providing a standardized way for the server to send content to the browser without being solicited by the client, and allowing for messages to be passed back and forth while keeping the connection open. In this way, a two-way (bi-directional) ongoing conversation can take place between a browser and the server.
  • 14. C++ Day 2017 – Un evento dell’Italian C++ Community Websocket WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection. The WebSocket protocol enables interaction between a browser and a web server with lower overheads, facilitating real-time data transfer from and to the server. This is made possible by providing a standardized way for the server to send content to the browser without being solicited by the client, and allowing for messages to be passed back and forth while keeping the connection open. In this way, a two-way (bi-directional) ongoing conversation can take place between a browser and the server.
  • 15. C++ Day 2017 – Un evento dell’Italian C++ Community Websocket WebSocket is a computer communications protocol, providing full-duplex communication channels over a single TCP connection. The WebSocket protocol enables interaction between a browser and a web server with lower overheads, facilitating real-time data transfer from and to the server. This is made possible by providing a standardized way for the server to send content to the browser without being solicited by the client, and allowing for messages to be passed back and forth while keeping the connection open. In this way, a two-way (bi-directional) ongoing conversation can take place between a browser and the server.
  • 16. C++ Day 2017 – Un evento dell’Italian C++ Community websocket advantage #1 Browsers don't enforce the Same Origin Policy (and its CORS relaxation) for WebSockets as opposed to AJAX calls (*) => no webserver needed (*) still, a websocket server can restrict access by checking "origin"
  • 17. C++ Day 2017 – Un evento dell’Italian C++ Community websocket advantage #2 Provides a standardized way for the server to send content to the browser without being solicited by the client. The WebSocket protocol enables interaction between a browser and a web server with lower overheads, facilitating real-time data transfer from and to the server. => Solves the problem of pushing events to the client
  • 18. C++ Day 2017 – Un evento dell’Italian C++ Community #1: bring in websockets Client (javascript): overly simple var ws = new WebSocket( 'ws://localhost:9971' ); ws.onmessage = function(msg) { console.log(msg); } ws.onopen = function () { console.log( 'WS connected' ); } ws.onclose = function () { console.log( 'WS closed' ); } ws.onerror = function () { console.log( 'WS error' ); } … if (ws.readyState == ws.OPEN) ws.send( 'hello world!' );
  • 19. C++ Day 2017 – Un evento dell’Italian C++ Community #1: bring in websockets Server (C++): websocket library boost::beast - asynchronous (foster single thread) - boost::asio paradigm (proactor and reactor) - coming to Boost 1.66.0 - interface a little too much error-prone for my taste 
  • 20. C++ Day 2017 – Un evento dell’Italian C++ Community #2: choose a data serialization format Json is the format with less friction for Javascript var obj = { foo: 'foo string', bar: 42 }; var jsonString = JSON.stringify( obj ); // serialize var jsonObj = JSON.parse( jsonString ); // deserialize assert( jsonObj.foo === 'foo string' ); assert( jsonObj.bar === 42 );
  • 21. C++ Day 2017 – Un evento dell’Italian C++ Community #2: choose a data serialization format On the C++ side: libraries to convert data <-> JSON (e.g., nlohmann json) // create object from string literal json j = "{ "happy": true, "pi": 3.141 }"_json; // or even nicer with a raw string literal auto j2 = R"( { "happy": true, "pi": 3.141 } )"_json; // explicit conversion to string std::string s = j.dump(); // {"happy":true,"pi":3.141} json j2 = { {"pi", 3.141}, {"happy", true}, {"name", "Niels"}, {"nothing", nullptr}, {"answer", { {"everything", 42} }}, {"list", {1, 0, 2}}, {"object", { {"currency", "USD"}, {"value", 42.99} }} };
  • 22. C++ Day 2017 – Un evento dell’Italian C++ Community Choices, as usual We need to decide which part goes into the C++ component and which into the Javascript client
  • 23. C++ Day 2017 – Un evento dell’Italian C++ Community Not so bad… We're forced to do something we usually don't do with classes inside the same component: Carefully design the interface between the two components.
  • 24. C++ Day 2017 – Un evento dell’Italian C++ Community First try: Dumb Client The protocol objects are the html graphical widgets Events (js -> C++): "button X has been pressed" Commands (C++ -> js): "set the text of label Y to Z" Javascript client is a dumb proxy
  • 25. C++ Day 2017 – Un evento dell’Italian C++ Community Packaging… We want the usual desktop application behaviour. => just add a script that launches the .exe and then the browser … with a server shutdown when the connection is lost. REM file softphone.cmd @echo off cd content start "" ui_websocket.exe start "" index.htm exit
  • 26. C++ Day 2017 – Un evento dell’Italian C++ Community C++ side Javascript side void OnIncomingCall() { using json = nlohmann::json; json msg = { { "id", "statuslabel" } { "request", "setlabel" }, { "value", "Incoming" } }; webSocket.Send( msg.dump() ); } webSocket.onmessage = function (event) { var jsonObj = JSON.parse(event.data); var item = document.getElementById(jsonObj.id); switch (jsonObj.request) { case "setlabel": item.innerHTML = jsonObj.value; break; case "setprogressbar": item.style.width = jsonObj.value; break; … } };
  • 27. C++ Day 2017 – Un evento dell’Italian C++ Community Javascript side C++ side function onCallClick() { var ev = { event: 'onclick', source: 'callbtn' }; webSocket.send( JSON.stringify(ev) ); } function onHangupClick() { var ev = { event: 'onclick', source: 'hangupbtn' }; webSocket.send( JSON.stringify(ev) ); } webSocket.OnMessage( [&](const string& msg){ using json = nlohmann::json; auto jsonObj = json::parse(msg); auto source = jsonObj.at("source"); auto event = jsonObj.at("event"); auto handler = handlers.find( make_pair(source, event) ); if (handler != handlers.end()) handler->second(); } );
  • 28. C++ Day 2017 – Un evento dell’Italian C++ Community Improvement #1 webSocket.onmessage = function (event) { eval( event.data ); }; void OnIncomingCall() { webSocket.Send("document.getElementById('statuslabel').innerHTML='Incoming'"); }
  • 29. C++ Day 2017 – Un evento dell’Italian C++ Community Improvement #2 $(function () { // all the buttons var buttons = document.getElementsByTagName('button'); for (var i = 0; i < buttons.length; i++) { var button = buttons[i]; button.onclick = function () { const ev = { event: 'onclick', id: this.id }; webSocket.send( JSON.stringify(ev) ); }; } // same for inputs etc. } webSocket.OnMessage( [&](const string& msg){ using json = nlohmann::json; auto jsonObj = json::parse(msg); auto source = jsonObj.at("source"); auto event = jsonObj.at("event"); auto handler = handlers.find( make_pair(source, event) ); if (handler != handlers.end()) handler->second(); } );
  • 30. C++ Day 2017 – Un evento dell’Italian C++ Community Can you spot the asimmetry? It seems like we can register javascript callbacks to C++ events But not the other way around! The asimmetry is due to languages differences: Javascript eval can exec an arbitrary string
  • 31. C++ Day 2017 – Un evento dell’Italian C++ Community Are we done, then? … not really. All the work is done by C++ (even input validation!) It's far better if the protocol speaks in terms of domain (e.g., phone call, ringtone, speaker, microphone,…): - input validation in javascript - better separation between app logic and UI - app logic independent from the UI representation
  • 32. C++ Day 2017 – Un evento dell’Italian C++ Community An higher level protocol… Direction: UI javascript -> C++ Application { "request": "connection", "data": { "server": "127.0.0.1", "user": "daniele", "password": "123456" } } { "request": "call", "data": { "number": "338123456" } } Direction: C++ Application -> UI javascript { "event": "levelschanged", "data": { "miclevel": 32, "speakerlevel": 73 } } { "event": "regstatuschanged", "data": { "status": "unregistered" } }
  • 33. C++ Day 2017 – Un evento dell’Italian C++ Community Too much code to write? // QT code for event handling void Ui::AutoanswerActive(bool active) { softPhone.Autoanswer(active)); } connect(autoanswerCheckBox, SIGNAL(clicked(bool)), this, SLOT(AutoanswerActive(bool))); // equivalent code handlers["autoanswer"] = [&](json event){ bool active = event.at("active"); softPhone.Autoanswer(active); });
  • 34. C++ Day 2017 – Un evento dell’Italian C++ Community Too much code to write? using json = nlohmann::json; std::unordered_map<std::string, std::function<void(json)>> handlers; webSocket.OnMessage( [&](const string& msg){ auto jsonObj = json::parse(msg); auto event = jsonObj.at("event"); auto handler = handlers.find( event) ); if (handler != handlers.end()) handler->second(jsonObj); } );
  • 35. C++ Day 2017 – Un evento dell’Italian C++ Community "…but javascript sucks!" … you can even use C++ inside the browser!
  • 36. C++ Day 2017 – Un evento dell’Italian C++ Community Emscripten emcc is a LLVM back end that produces asm.js
  • 37. C++ Day 2017 – Un evento dell’Italian C++ Community asm.js function Vb(d) { d = d | 0; var e = 0, f = 0, h = 0, j = 0, k = 0, l = 0, m = 0, n = 0, o = 0, p = 0, q = 0, r = 0, s = 0; e = i; i = i + 12 | 0; f = e | 0; h = d + 12 | 0; j = c[h >> 2] | 0; if ((j | 0) > 0) { c[h >> 2] = 0; k = 0 } else { k = j } j = d + 24 | 0; if ((c[j >> 2] | 0) > 0) { c[j >> 2] = 0 } ... } Intermediate programming language intended to simulate Assembler. It's a small subset of JavaScript optimized for performances. Runs everywhere, but all the four major browsers optimize for asm.js
  • 38. C++ Day 2017 – Un evento dell’Italian C++ Community Emscripten APIs supported C++ standard libraries which don’t need to interact with the system - Network support (libc-style, non-blocking only(!)) - File system access - Graphics (OpenGL ES) - Audio, keyboard, mouse, joystick (SDL) - Integration with HTML5
  • 39. C++ Day 2017 – Un evento dell’Italian C++ Community Emscripten usage •Game Engines(!) • UE3 (reported to be ported in 4 days) • UE4 • Unity (C# to C++ with IL2CPP and C++ to asm.js with Emscripten) •Games • Quake 3 • Doom • OpenDune •Libraries/Frameworks • OpenSSL • SQLite • Pepper (via pepper.js) • Quite a few of Qt demos
  • 40. C++ Day 2017 – Un evento dell’Italian C++ Community Emscripten usage •Game Engines(!) • UE3 (reported to be ported in 4 days) • UE4 • Unity (C# to C++ with IL2CPP and C++ to asm.js with Emscripten) •Games • Quake 3 • Doom • OpenDune •Libraries/Frameworks • OpenSSL • SQLite • Pepper (via pepper.js) • Quite a few of Qt demos
  • 41. C++ Day 2017 – Un evento dell’Italian C++ Community Does it make sense? We have different materials, like statically typed and dynamically typed languages, yet we don't have a sound theory of forces, so we end up with the usual evangelist trying to convert the world to its material of choice. It's kinda funny, because it's just as sensible as having a Brick Evangelist trying to convince you to use bricks instead of glass for your windows ("it's more robust!"), and a Glass Evangelist trying to convince you to build your entire house out of glass ("you'll get more light!"). Carlo Pescio
  • 42. C++ Day 2017 – Un evento dell’Italian C++ Community Let's recap A "one size fits all" approach never works It's just a new way you can take into account: - Crossplatform (as much as the C++ you write) - No constraint on your C++ code (no hugly macros, no custom compilers, …) - Sharp separation between UI and app logic - Multiple skins - Automatic test of the whole application (plugging a test websocket client) - You can use the whole toolset available for JS (people included) - Idea useful also in other languages (see scripting languages) But – please – split the application the right way!
  • 43. C++ Day 2017 – Un evento dell’Italian C++ Community References i=43 Me: @DPallastrelli Me: it.linkedin.com/in/pallad Github: http://github.com/daniele77

Editor's Notes

  1. Ciao, Io vorrei fare una chiacchierata sulle UI in C++
  2. Come sappiamo, il C++ è praticamente la scelta obbligata quando abbiamo una o più di quelle esigenze lì in fondo (alte prestazioni, stretta interazione con l'HW, codice legacy). In realtà qualcuno si ostina a usare ancora il C, non si capisce bene perché, ma questo sarebbe un altro talk. Ah, e poi ovviamente c'è il motivo più importante, che non ho elencato lì ma capita spesso anche nell'industria, cioè che il C++ è il nostro linguaggio preferito  In alcuni di questi casi (non tanti per la verità) è necessario interagire tramite un'interfaccia grafica, ad esempio nel caso delle applicazioni desktop (es. backend di un simulatore, ma anche nel caso dell'embedded mi è capitato di avere sistemi che integrano un display touch-screen da 10" magari con una dashboard, o sistemi chiosco, etc.) Ecco, io vorrei parlarvi di una soluzione che ho adottato con successo in diversi contesti, In alcuni casi, funziona bene. Allora, in generale, quali sono le possibilità per le UI? [slide successiva]
  3. Facciamo una breve panoramica delle possibilità che abbiamo per ottenere delle GUI (grafiche) in applicazioni desktop C++. Partiamo da quelle a più basso livello. Ovviamente scorderò molte possibilità, ma è per dare un'idea delle diverse possibilità che abbiamo, coi limiti di ciascuno.
  4. Io uso il C++ da … praticamente 23 anni, prima come studente, poi come professionista Fatto sta che personalmente non sono mai stato pienamente soddisfatto delle soluzioni disponibili per le UI di applicazioni desktop in C++. Alcuni sono immensi altri ristretti ai widget per la UI Alcuni usano complesse macro o preprocessori Molte non usano C++ moderno (alcune nate 20 anni fa) Alcune si reimplementano la libreria standard! Widget nativi VS widget non nativi Alcuni sono proprio considerati un linguaggio a parte E comunque – è inutile -- non si riesce mai a ottenere un risultato bello come con le tecnologie web. Molto dipende forse dal tipo di applicazioni che faccio, o da come le faccio, ma in generale Non mi piace legarmi a dei mastodonti che pretendono di avere il controllo completo sulla mia applicazione Non mi va di portarmi dietro un baraccone che comprende ogni cosa Vorrei usare C++ moderno, o comunque non essere vincolato dalla libreria che voglio usare solo per la UI Voglio essere libero di usare la libreria standard o altre librerie di mia scelta per ogni parte
  5. … probabilmente non voglio usare un framework
  6. L'alternativa che avrei sempre voluto sperimentare è quella di aggiungere una UI html alle mie applicazioni. Senza portarmi dietro tutto un web server o anche grossi framework, perché non si capisce perché per avere una UI mi devo portar dietro tutte le librerie immaginabili, i suoi containers, il suo meccanismo di eventi, addirittura un suo meta-object compiler…
  7. Perché l'html? Perché non vedevo l'ora di impazzire anch'io col CSS? Perché in media consente più possibilità e una grafica migliore. Perché potrei dare la parte grafica da fare al mio grafico che è abituato a usare html e css, Per avere una divisione netta tra contenuto e presentazione E poi…
  8. E’ disponibile molto più materiale (info & lib) sull’html che su uno qualsiasi dei framework / librerie per UI C++
  9. Non è una soluzione universale Non va sempre bene Non è adatto a tutte le applicazioni E' solo una soluzione che ho usato con successo in diversi contesti e può essere uno spunto per qualcuno
  10. Questi sono alcune delle opzioni che ho provato prima di passare a quella definitiva: Usare l'http col long polling, Creare la mia applicazione come estensione di chrome, Fare la UI web dentro il WebEngine di Qt Impacchettare direttamente l'applicazione con chromium usando CEF Capite immediatamente che sono tutte soluzioni non particolarmente lightweigth, e alcune hanno anche dei problemi Per l'http devo per forza passare per un webserver e devo usare il long polling per informare la UI di quello che succede nell'applicazione E per quanto riguarda il Qt WebEngine, be', se volevo portarmi dietro Qt avevo già risolto il problema della UI
  11. finalmente con html5 la soluzione che cercavo a parte che le UI web si sono arricchite graficamente, finalmente è possibile caricare una pagina in locale che interagisca con un'applicazione nativa. Tutto questo grazie alle websocket.
  12. Non sono abituato a mettere così tanto testo in una slide, comunque… Le web socket le conoscete tutti credo,
  13. E' un protocollo full-duplex che funziona su una singola connessione TCP
  14. Fa parte di html5 quindi implementato nei browser
  15. E permette a un server di mandare messaggi al browser senza essere sollecitato
  16. Perché le websocket risolvono il mio problema di mettere un'interfaccia html alle mie applicazioni? Perché nel caso delle websocket il browser non controlla la SOP. (invece per l'http il browser controlla che le chiamate vengano fatte allo stesso server da cui è stata scaricata la pagina) Questo ci consente di non usare un webserver, e di avere la pagina html in locale e aprirla come file direttamente dal browser.
  17. Inoltre, risolvono il problema delle notifiche di eventi (push) Con AJAX ad esempio, dovevo usare il long polling. Bene, abbiamo trovato una tecnologia promettente, non ci resta che sfruttarla per i nostri scopi.
  18. Lato javascript, è facilissimo comunicare tramite una websocket
  19. In C++ dobbiamo trovare una libreria, non è facilissimo. Io ho usato questa, perché nel mio caso ha il pregio di essere ascinrona e di adattarsi all'idioma di boost asio. Anzi, verrà inserita nella prossima versione di boost, e dovrebbe essere una garanzia.
  20. Abbiamo trovato il canale di comunicazione, dobbiamo decidere il formato dei messaggi da farci passare. JSON ci rende sicuramente la vita molto facile lato javascript
  21. Lato C++ esistono librerie moderne per gestire il formato JSON [descrizione nlohmann json]
  22. Lato tecnologico siamo a posto. Abbiamo due componenti, uno C++ e uno Javascript Adesso siamo costretti a pensare subito a cosa mettere da una parte e cosa dall'altra
  23. … dover definire un protocollo da definire, di passare per un canale, e di avere completamente separati gli artifatti di UI e applicazione [come chiamarla?] ci impone di fare qualcosa che a volte non facciamo: Pensare (e progettare) l’interfaccia tra due componenti. vantaggio ulteriore: siamo costretti a dividere bene tra Ui e logica applicativa. [digressione: perché vanno tanto di moda microservice & c? perché abbiamo scoperto l'acqua calda di pensare alle interfacce tra componenti, cosa che potremmo/dovremmo fare anche all'interno di una singola applicazione, suddividendola in piccoli componenti/classi, che si parlano tramite messaggi/metodi...]
  24. La tentazione (che in effetti rende più generale possibile la soluzione) è quella di far parlare il protocollo in termini di widget (es. il bottone X è stato premuto, cambia il testo della label, etc...) Il codice non ve lo faccio vedere, è troppo stupido. Javascript rileva gli eventi dei widget della UI, li manda in json sulle websocket e viceversa. La parte C++ usa i widget come se usasse una normale libreria grafica, ma invece c'è del codice che manda del json sulle weboscket. Invece vi faccio vedere che funziona… [aprire l'esempio, doppio click sul .exe e poi sul .html] questo è un semplice esempio che dimostra chiaramente... quanto sono scarso a disegnare UI :-) … ma anche che è possibile avere un'applicazione desktop con una UI html senza webserver Questo è un esempio totalmente finto di softphone (visto che io lavoro nel campo della telefonia). Abbiamo un'applicazione C++ che fa da softphone, vogliamo aggiungere una UI, usiamo l'html. Si vede che posso mandare dei comandi per la UI spontanei e in tempo reale (es. VU meter, stato registrazione) e eventi della UI al componente C++ (es. premo il bottone della connessione, della chiamata, etc) notare che ho aperto la pagina facendo direttamente doppio click (non ho webserver, no SOP)
  25. Già che ci siamo… Noi vogliamo un'applicazione desktop che sembri la solita, voglio distribuire un pacchetto con un unico eseguibile che fa tutto. Molto semplice. Impacchettiamo tutto quello che ci serve in una directory e facciamo uno script che lanci prima il server nativo e poi il browser. Già che ci siamo facciamo anche lo shutdown del server quando perde la connessione, così se chiudiamo la UI termina anche l'applicazione. Possiamo ovviamente intercettare l'evento e chiedere se vogliamo salvare etc. etc. [demo due. Mi assicuro che non ci siano più parti della demo 1 che girano. Faccio doppio click sul .cmd e dovrebbe aprirsi tutto. Faccio notare che l'applicazione non ha finestra. Faccio vedere un po' di cose della gui, e poi chiudo il browser. Faccio vedere che non c'è più il server che gira.]
  26. Un primo miglioramento che ci consente di ridurre molto il codice è questo. Qui si vede che dal C++ eseguiamo direttamente comandi javascript che vanno a modificare il DOM. Lato client siamo completamente trasparenti. Non stiamo più usando JSON. Buttiamo via tutto il codice che serve per codificare e decodificare in un terzo formato (JSON).
  27. Nella direzione inversa siamo costretti a intercettare tutti gli eventi di interesse (lato js) e spedirli al cpp con qualche convenzione. Lato cpp devo poi associare agli eventi delle callback. Posso migliorare in parte con quel codice lì, che associa automaticamente un messaggio JSON a ogni evento Insomma: in questo senso non ci posso fare molto.
  28. Purtroppo non è simmetrico. Da un lato è come se potessimo agganciare delle callback javascript a eventi che nascono nella parte C++, Ma dall'altra non possiamo fare lo stesso. Non possiamo associare (direttamente) al click di un bottone del codice C++. Dobbiamo farci uno strato che converta l'evento in un protocollo, che venga decodificato e associato a codice C++. Non possiamo eseguire direttamente codice C++ da javascript! L’asimmetria è dovuta alle proprietà diverse dei due linguaggi (qualcuno direbbe che abbiamo a che fare con materiali diversi). Praticamente da un lato abbiamo eval, dall’altro no, che consente di trasformare una stringa *arbitraria* in codice eseguibile.
  29. Abbiamo ottenuto quello che volevamo, vi ho anche fatto vedere che funziona. Va bene così? Non è la soluzione che uso io di solito. Vi ricordate quando dicevo che dobbiamo scegliere attentamente l'interfaccia tra i due componenti? Noi abbiamo messo praticamente tutto lato C++. Lato javascript abbiamo solo un piccolissimo strato che serve per inoltrare gli eventi dei widget. Abbiamo messo in C++ anche la validazione dell'input, in cui di solito, javascript è più forte, ha anche librerie specifiche. Poi così facendo mischiamo il codice della UI con quello applicativo tutto in C++. Magari noi siamo molto bravi, ma io ho visto spesso in questi casi che il codice relativo alla presentazione andava a finire negli strati più profondi dell'applicazione. Cosa passa nel protocollo? Stringhe che parlano di widget. Invece: facciamo un protocollo che parla in termini del dominio applicativo, in modo da confinare tutta la parte relativa nell'interfaccia grafica nella parte javascript. --- Abbiamo ottenuto un'applicazione desktop C++ con un'interfaccia html, Ci siamo scritti la nostra libreria per inoltrare gli eventi da una parte all'altra. L'abbiamo anche impacchettata e riusciamo a farla sembrare quasi un'applicazione unica. A posto così? No, non proprio. Con questo taglio tra parte client e server abbiamo ottenuto un client veramente stupido, che si limita a inoltrare comandi e eventi per i suoi widgets. Tutta l'elaborazione, è spostata lato C++. Proprio tutta, compresa ad esempio la validazione della UI è scritta in c++. Secondo me abbiamo perso un'occasione. Quella di parlare in termini di dominio del problema. Pensateci: nelle websocket che stringhe passano? "callbtn", "onclick", roba del genere. In realtà, l'utente parla in termini di oggetti del dominio: "chiamata telefonica", "libero", "occupato", "suoneria", "altoparlante", "microfono", etc. Cosa succede allora a adottare una soluzione alternativa, meno generale (nel senso che non posso mettere tutto in una libreria che valga per tutte le applicazioni del mondo), in cui occorra approfondire un po' meglio il dominio applicativo? [in fondo, la prima cosa da fare quando si sviluppa software, è studiare il dominio applicativo, no?] Cerchiamo di mantenere la logica della UI confinata al componente html/javascript, Più vicino alla parte grafica, d'altra parte cose che vanno a toccare le stesse parti devono stare vicine. Ad esempio: la validazione della UI è giusto che stia insieme alla UI, perché se cambio una probabilmente cambierò anche l'altra. Separiamo nettamente l'applicazione dalla "presentazione". Ottengo diversi vantaggi: - Innanzitutto sono costretto a separare nettamente la logica dell'applicazione dalla UI. Quando uso uno stesso linguaggio per tutto è facile vedere mischiati concetti completamente diversi, La parte C++ è completamente indipendente dalla UI. E' giusto, perché io adesso vi ho fatto vedere un'interfaccia a bottoni, ma potrei cambiarla e farla diventare grafica, magari disegnata come un telefono vero… SPIEGARE MEGLIO I VANTAGGI, CAZZAROLA (posso modificare la UI in maniera indipendente, posso mettere la validazione insieme alla logica della UI) Protocollo: dovrei forse farmi un proxy in javascript identico a quello in C++ e poi mandare del JSON custom ad ogni invocazione di metodo? -
  30. Un'idea potrebbe essere qualcosa del genere. Vedete che parliamo in termini telefonici, ovviamnete così non possiamo più avere codice che traduce automaticamnete in eventi o azioni sulla UI
  31. Quindi, dobbiamo progettare un protocollino. Se vi state chiedendo se è molto più codice, vi faccio vedere che è paragonabile…
  32. … una volta che avete un meccanismo per associare handler agli eventi che arrivano, che cmq è riusabile.
  33. Per chi non amasse javascript e volesse fare l'integralista, a scopo di curiosità vi faccio vedere che potrei usare il C++ anche lato client, al posto di javascript.
  34. registers (implemented as JavaScript vars) Ability to access memory (as one huge array; in the example above – c[])
  35. ... cito una frase di Carlo, spero non troppo a sproposito, che dice:
  36. Quindi, ricapitolando. La mia intenzione era quella di proporre un'idea diversa dal solito per le UI delle applicazioni desktop in C++ Una soluzione che ho adottato con successo in diverse occasioni. Non è una soluzione universale, in alcuni contesti non ha ovviamente senso. È una soluzione portabile (quanto lo è il vostro codice C++) Non vi vincola in alcun modo nella scrittura della parte C++ (so che lo apprezzerete): niente struttura predefinita, niente orribili macro, niente precompilatori, niente librerie omnicomprensive. Vi permette di concentrarvi prima sulla logica della vostra applicazione, senza inquinarla con concetti relativi alla presentazione. Vi permette in maniera molto semplice di effettuare test automatici del vostro applicativo, sostituendo alla UI un sistema di test che parli con le websocket. Per la parte grafica potrete dare sfogo alla vostra creatività (o avvalervi di un grafico), e tutta la parte di validazione verrà fatta con javascript… e vi potrete avvalere delle relative librerie e framework. Potrete sostituire facilmente la parte grafica e avere skin per l'applicazione, anche sviluppate dall'utente. L'idea di utilizzare html5 per le UI parlando con websocket può venire comoda anche per tutti quei linguaggi di script che non hanno una loro interfaccia. Non javascript :-) ma ad esempio, ruby. Spero di avervi convinto che è meglio spezzare l'applicazione in modo da parlare con messaggi che riguardano il dominio applicativo
  37. Questi sono i miei contatti. C'è anche il contatto della mia azienda, leader italiano per i sistemi di bordo di informazione ai passeggieri per treni e metropolitane, ha la sede a Bologna e un laboratorio a Piacenza, e stiamo assumendo sviluppatori, quindi se qualcuno fosse interessato, vi invito a dare un'occhiata al sito, o a contattarmi direttamente.