SlideShare a Scribd company logo
STL/boost and Qt
Daniel Eriksson / Johan Thelin
1
Abstract
Showing how to implement patterns popularized by Qt using boost and STL.
2
Who are we?
Daniel Eriksson
● Programming in C++ since 2005
● Using Qt since 2012
Johan Thelin
● Using Qt since 1998
● Trolltech / Pelagicore /
Luxoft / Kuro Studio
● Foundations of Qt Development
● QmlBook (qmlbook.org)
● Datormagazin
● foss-gbg / foss-north
3
Contents
1. The problem we want to solve (loose connection between objects)
2. The Observer Pattern
3. Qt signal and slots
4. Boost::signals2
5. Synapse
4
The problem we want to solve
● To connect objects together without them knowing about each other. I.e.
object A does not have an explicit dependency to object B
○ Connect many subscribers to one source (publisher)
○ Connect these objects without direct dependencies
■ Rather interface based
5
The Observer Pattern
6
Observer example
7
The QObject
● Signals and slots
● Properties
● Introspection
● Object ownership
● Basically Java features in C++
● Part of the QtCore module
8
QObject Example
class Person : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
Person(QObject *parent=0);
Person(const QString &name, QObject *parent=0);
QString name() const;
public slots:
void setName(const QString &name);
signals:
void nameChanged(const QString &name);
private:
// ...
};
9
QObject Example - QObject and Q_OBJECT
class Person : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
Person(QObject *parent=nullptr);
Person(const QString &name, QObject *parent=nullptr);
QString name() const;
public slots:
void setName(const QString &name);
signals:
void nameChanged(const QString &name);
private:
// ...
};
QObject is the base class for most non-POD Qt
classes.
Q_GADGET is a light weight alternative - can
have properties, enums and invokables. No
signals and slots.
Q_OBJECT sets up the needed tables for the
introspection.
10
QObject Example - Ownership
class Person : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
Person(QObject *parent=nullptr);
Person(const QString &name, QObject *parent=nullptr);
QString name() const;
public slots:
void setName(const QString &name);
signals:
void nameChanged(const QString &name);
private:
// ...
};
Each QObject can have a parent. This is the
object ownership tree.
A parent destroys is children upon destruction.
11
QObject Example - Signals and Slots
class Person : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
Person(QObject *parent=nullptr);
Person(const QString &name, QObject *parent=nullptr);
QString name() const;
public slots:
void setName(const QString &name);
signals:
void nameChanged(const QString &name);
private:
// ...
};
Slots (callbacks) are ordinary methods placed in
the public/protected/private slots
sections.
Signals (calls callbacks) are method signatures
placed in the signals sections.
The slots keyword is dropped by the
pre-processor. The signals keyword is turned
into protected by the the pre-processor.
Q_INVOKABLE creates callables that are not
setters.
12
QObject Example - Properties
class Person : public QObject {
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
Person(QObject *parent=nullptr);
Person(const QString &name, QObject *parent=nullptr);
QString name() const;
public slots:
void setName(const QString &name);
signals:
void nameChanged(const QString &name);
private:
// ...
};
The policy since ancient times has been to create
triplets: foo, setFoo, fooChanged.
These can be further associated using the
Q_PROPERTY macro.
Great for QML / Javascript / Python integration!
13
The Qt Meta Object Compiler
*.h
*.cpp
moc moc_*.cpp compiler
*.o
linkerbinary
Here goes the
introspection
data that
enables “magic”.
Sources
Tools
Intermediary
Result
14
QObject Connecting
Person *person = new Person("Kalle");
QLabel *label = new QLabel();
connect(person, SIGNAL(nameChanged(QString)), label, SLOT(setText(QString)));
connect(person, &Person::nameChanged, label, QLabel::setText);
connect(person, &Person::nameChanged, [=] () { qDebug("Name changed!"); });
● Use qOverload<signature>(function) to be specific (C++14)
● You can also connect signals to signals for propagation
15
QObject Disconnecting
Person *person = new Person("Kalle");
QLabel *label = new QLabel();
connect(person, SIGNAL(nameChanged(QString)), label, SLOT(setText(QString)));
connect(person, &Person::nameChanged, label, QLabel::setText);
connect(person, &Person::nameChanged, [=] () { qDebug("Name changed!"); });
disconnect(person, SIGNAL(nameChanged(QString)), label, SLOT(setText(QString)));
disconnect(person, &Person::nameChanged, label, QLabel::setText);
disconnect(person, 0, label, 0);
person->disconnect(label);
disconnect(person, &Person::nameChanged, 0, 0);
person->disconnect(SIGNAL(nameChange(QString)));
disconnect(person, 0, 0, 0); The anonymous lambda cannot be disconnected explicitly.
16
Benefits of defining a main-loop
● Connections across threads
○ Depends on QMetaType system for serialization of arguments
○ Uses the thread affinity of each object, see QObject::thread
○ Makes connections asynchronous by default, but can be made blocking
■ connect(..., …, …, …, Qt::ConnectionType);
■ Can be auto, direct, queued, blocking-queued
■ Can also be unique
● The method QObject::deleteLater is useful for decoupling
○ Allows the whole call stack to complete prior to destroying an object
○ Can help simplify dependencies / reduce the number of needed callback points
17
QObject and Observable
● QObject is a generic observable
● Each signal is a point to connect callbacks to
● Each slot is a potential callback
● Adds more run-time introspection, e.g.
○ names of things, property concept
○ Inheritance tree, list of available methods, etc
○ Nice for language bindings - not needed for C++ except in a very dynamic context
18
Some words about boost
● Boost is free portable C++ library
● “establish ‘existing practice’ and provide reference implementations so that
Boost libraries are suitable for eventual standardization”
● Peer-reviewed
● Kind of an incubator for new C++ library features
19
The boost::signals2 library
● Signals2 library provides two fundamental object types
● Signal
○ boost::signals2::signal<void (float, int)> sig
● Connection
○ Boost::signals2::connect = sig.connect(boost::bind(<some signal
handler func>)
20
NewsProducer / NewsConsumer Example
#include <boost/signals2/signal.hpp>
class NewsProdcuer {
public:
using NewsUpdate = boost::signals2::signal<void (std::string)>;
using NewsUpdateSubscriber = NewsUpdate::slot_type;
NewsProdcuer() {}
boost::signals2::connection connectSubscriber(const NewsUpdateSubscriber& subscriber) {
return newsUpdate.connect(subscriber);
}
void publish(const std::string& news) {
newsUpdate(news);
}
private:
NewsUpdate newsUpdate;
};
21
NewsProducer / NewsConsumer Example
class NewsConsumer {
public:
NewsConsumer(const std::string& name, NewsProdcuer& producer) : m_consumerName(name) {
m_newsProducerConnection = producer.connectSubscriber(boost::bind(&NewsConsumer::handleNewsUpdate, this, _1));
}
~NewsConsumer() {
m_newsProducerConnection.disconnect();
}
private:
void handleNewsUpdate(const std::string update) {
std::cout << m_consumerName << ": " << update << std::endl;
}
std::string m_consumerName;
boost::signals2::connection m_newsProducerConnection;
};
22
NewsProducer / NewsConsumer Example
Usage:
NewsProdcuer producer;
NewsConsumer consumer1("Consumer 1", producer);
NewsConsumer consumer2("Consumer 2", producer);
producer.publish("News update");
Output:
Consumer 1: News update
Consumer 2: News update
23
Some features of signals2
● Signals2 can handle results from the different subscribers
● Signals can be blocked temporarily in a particular connection without
disconnecting
○ I.e the slot will not be called even if the signal is emitted
24
Handling results
// aggregate_values is a combiner which places all the values returned
// from slots into a container
template<typename Container>
struct aggregate_values
{
typedef Container result_type;
template<typename InputIterator>
Container operator()(InputIterator first, InputIterator last) const
{
Container values;
while(first != last) {
values.push_back(*first);
++first;
}
return values;
}
};
25
Handling results
boost::signals2::signal<float (float, float),
aggregate_values<std::vector<float> > > sig;
sig.connect(&quotient);
sig.connect(&product);
sig.connect(&sum);
sig.connect(&difference);
std::vector<float> results = sig(5, 3);
std::cout << "aggregate values: ";
std::copy(results.begin(), results.end(),
std::ostream_iterator<float>(std::cout, " "));
std::cout << "n";
26
Drawbacks of signals2
● No automatic transfer of control from a sender of a signal to a receiver
● I.e if the work in a slot shall take place in another thread than the sender of
the signal that thread switch needs to be implemented by the user.
27
In boost::signals2 in conclusion
● Boost::signals2 provides a framework to implement signal/slot mechanism
without needing to implement all the boilerplate oneself
● Not as flexible as QObject
● Not possible to transfer control between threads using signal/slots as in Qt
28
The Synapse library
● Another signals/slot like library
● Submitted to boost for review but nothing has happened in the last 3
months…
● Very similar to boost::signals2
● Have the ability to transfer control between threads
29
Defining signals in Synapse and emitting them
struct this_signal_;
typedef this_signal_(*this_signal)(int);
struct that_signal_;
typedef that_signal_(*that_signal)(int);
synapse::emit<that_signal>(5);
30
Example (from the documentation)
typedef struct clicked_(*clicked)();
class button {
public:
void click() {
synapse::emit<clicked>(this);
}
};
31
Example (from the documentation)
class dialog {
public:
void accept();
};
....
shared_ptr<button> emitter=make_shared<button>();
shared_ptr<dialog> receiver=make_shared<dialog>();
synapse::connect<clicked>(emitter, receiver, &dialog::accept);
32
Synapse
● The emitter object can be any type.
● Signal types are not tied to the type of the emitter.
○ Signals can be added to existing types
● The author argues that since the signals are not tied to a type something like
the MOC of Qt is not necessary
● The author argues that signals shall be held separate from the emitters.
● Provides a convenience object to implement transfer of control between
threads: thread_local_queue
33
Without thread local queue
34
Thread local queue
35
Inter thread communication
● The thread_local_queue object has the following methods
○ Post
○ Poll
○ Wait
● Life-time of arguments needs to be managed explicitly, i.e. no serialization
36
Inter thread communication
● Documentation suggests that posting on a thread_local_queue is handled
automatically
● Probably the user needs to handle this is an slot/callback and post the events
to the queue
37
Synapse conclusions
● Signals2 seems more robust
● The thread_local_queue is a nice feature
38
Thank you!
39
References
● Boost: https://www.boost.org/
● Boost::signals2: https://www.boost.org/doc/libs/1_68_0/doc/html/signals2.html
● Synapse: https://zajo.github.io/boost-synapse/
● Qt: https://www.qt.io/
40

More Related Content

Similar to Observer pattern with Stl, boost and qt

Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2
Emertxe Information Technologies Pvt Ltd
 
Start Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New RopeStart Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New Rope
Yung-Yu Chen
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and Destructors
Keyur Vadodariya
 
(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_types(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_types
Nico Ludwig
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrencypriyank09
 
New c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_iNew c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_i
Nico Ludwig
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloaded
cbeyls
 
Object oriented programming with java pdf
Object oriented programming with java pdfObject oriented programming with java pdf
Object oriented programming with java pdf
sonivipin2342
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascript
Ayush Sharma
 
Devoxx 2015 - Building the Internet of Things with Eclipse IoT
Devoxx 2015 - Building the Internet of Things with Eclipse IoTDevoxx 2015 - Building the Internet of Things with Eclipse IoT
Devoxx 2015 - Building the Internet of Things with Eclipse IoT
Benjamin Cabé
 
A closure ekon16
A closure ekon16A closure ekon16
A closure ekon16
Max Kleiner
 
Qt for beginners part 1 overview and key concepts
Qt for beginners part 1   overview and key conceptsQt for beginners part 1   overview and key concepts
Qt for beginners part 1 overview and key concepts
ICS
 
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
PROIDEA
 
Classes and object
Classes and objectClasses and object
Classes and object
Ankit Dubey
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndEdward Chen
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)Sri Prasanna
 
Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....
Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....
Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....
AboutYouGmbH
 
Take advantage of C++ from Python
Take advantage of C++ from PythonTake advantage of C++ from Python
Take advantage of C++ from Python
Yung-Yu Chen
 
Design patterns - Common Solutions to Common Problems - Brad Wood
Design patterns -  Common Solutions to Common Problems - Brad WoodDesign patterns -  Common Solutions to Common Problems - Brad Wood
Design patterns - Common Solutions to Common Problems - Brad Wood
Ortus Solutions, Corp
 
The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202
Mahmoud Samir Fayed
 

Similar to Observer pattern with Stl, boost and qt (20)

Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2Qt Application Programming with C++ - Part 2
Qt Application Programming with C++ - Part 2
 
Start Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New RopeStart Wrap Episode 11: A New Rope
Start Wrap Episode 11: A New Rope
 
Constructors and Destructors
Constructors and DestructorsConstructors and Destructors
Constructors and Destructors
 
(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_types(3) cpp abstractions more_on_user_defined_types
(3) cpp abstractions more_on_user_defined_types
 
Java 5 concurrency
Java 5 concurrencyJava 5 concurrency
Java 5 concurrency
 
New c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_iNew c sharp3_features_(linq)_part_i
New c sharp3_features_(linq)_part_i
 
Android Loaders : Reloaded
Android Loaders : ReloadedAndroid Loaders : Reloaded
Android Loaders : Reloaded
 
Object oriented programming with java pdf
Object oriented programming with java pdfObject oriented programming with java pdf
Object oriented programming with java pdf
 
Design patterns in javascript
Design patterns in javascriptDesign patterns in javascript
Design patterns in javascript
 
Devoxx 2015 - Building the Internet of Things with Eclipse IoT
Devoxx 2015 - Building the Internet of Things with Eclipse IoTDevoxx 2015 - Building the Internet of Things with Eclipse IoT
Devoxx 2015 - Building the Internet of Things with Eclipse IoT
 
A closure ekon16
A closure ekon16A closure ekon16
A closure ekon16
 
Qt for beginners part 1 overview and key concepts
Qt for beginners part 1   overview and key conceptsQt for beginners part 1   overview and key concepts
Qt for beginners part 1 overview and key concepts
 
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
4Developers 2018: Ile (nie) wiesz o strukturach w .NET (Łukasz Pyrzyk)
 
Classes and object
Classes and objectClasses and object
Classes and object
 
CS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2ndCS225_Prelecture_Notes 2nd
CS225_Prelecture_Notes 2nd
 
Other Approaches (Concurrency)
Other Approaches (Concurrency)Other Approaches (Concurrency)
Other Approaches (Concurrency)
 
Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....
Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....
Dennis Benkert & Matthias Lübken - Patterns in a containerized world? - code....
 
Take advantage of C++ from Python
Take advantage of C++ from PythonTake advantage of C++ from Python
Take advantage of C++ from Python
 
Design patterns - Common Solutions to Common Problems - Brad Wood
Design patterns -  Common Solutions to Common Problems - Brad WoodDesign patterns -  Common Solutions to Common Problems - Brad Wood
Design patterns - Common Solutions to Common Problems - Brad Wood
 
The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202The Ring programming language version 1.8 book - Part 86 of 202
The Ring programming language version 1.8 book - Part 86 of 202
 

Recently uploaded

Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
abdulrafaychaudhry
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
wottaspaceseo
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
Tendenci - The Open Source AMS (Association Management Software)
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Anthony Dahanne
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
ayushiqss
 
Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
MayankTawar1
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
Cyanic lab
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
IES VE
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
Globus
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
AMB-Review
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
informapgpstrackings
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Shahin Sheidaei
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Globus
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
XfilesPro
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
XfilesPro
 

Recently uploaded (20)

Lecture 1 Introduction to games development
Lecture 1 Introduction to games developmentLecture 1 Introduction to games development
Lecture 1 Introduction to games development
 
How Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptxHow Recreation Management Software Can Streamline Your Operations.pptx
How Recreation Management Software Can Streamline Your Operations.pptx
 
Corporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMSCorporate Management | Session 3 of 3 | Tendenci AMS
Corporate Management | Session 3 of 3 | Tendenci AMS
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 
Why React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdfWhy React Native as a Strategic Advantage for Startup Innovation.pdf
Why React Native as a Strategic Advantage for Startup Innovation.pdf
 
Software Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdfSoftware Testing Exam imp Ques Notes.pdf
Software Testing Exam imp Ques Notes.pdf
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
GlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote sessionGlobusWorld 2024 Opening Keynote session
GlobusWorld 2024 Opening Keynote session
 
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdfDominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
Dominate Social Media with TubeTrivia AI’s Addictive Quiz Videos.pdf
 
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
Field Employee Tracking System| MiTrack App| Best Employee Tracking Solution|...
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
Gamify Your Mind; The Secret Sauce to Delivering Success, Continuously Improv...
 
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
Climate Science Flows: Enabling Petabyte-Scale Climate Analysis with the Eart...
 
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, BetterWebinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
Webinar: Salesforce Document Management 2.0 - Smarter, Faster, Better
 
Vitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume MontevideoVitthal Shirke Microservices Resume Montevideo
Vitthal Shirke Microservices Resume Montevideo
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 

Observer pattern with Stl, boost and qt

  • 1. STL/boost and Qt Daniel Eriksson / Johan Thelin 1
  • 2. Abstract Showing how to implement patterns popularized by Qt using boost and STL. 2
  • 3. Who are we? Daniel Eriksson ● Programming in C++ since 2005 ● Using Qt since 2012 Johan Thelin ● Using Qt since 1998 ● Trolltech / Pelagicore / Luxoft / Kuro Studio ● Foundations of Qt Development ● QmlBook (qmlbook.org) ● Datormagazin ● foss-gbg / foss-north 3
  • 4. Contents 1. The problem we want to solve (loose connection between objects) 2. The Observer Pattern 3. Qt signal and slots 4. Boost::signals2 5. Synapse 4
  • 5. The problem we want to solve ● To connect objects together without them knowing about each other. I.e. object A does not have an explicit dependency to object B ○ Connect many subscribers to one source (publisher) ○ Connect these objects without direct dependencies ■ Rather interface based 5
  • 8. The QObject ● Signals and slots ● Properties ● Introspection ● Object ownership ● Basically Java features in C++ ● Part of the QtCore module 8
  • 9. QObject Example class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) public: Person(QObject *parent=0); Person(const QString &name, QObject *parent=0); QString name() const; public slots: void setName(const QString &name); signals: void nameChanged(const QString &name); private: // ... }; 9
  • 10. QObject Example - QObject and Q_OBJECT class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) public: Person(QObject *parent=nullptr); Person(const QString &name, QObject *parent=nullptr); QString name() const; public slots: void setName(const QString &name); signals: void nameChanged(const QString &name); private: // ... }; QObject is the base class for most non-POD Qt classes. Q_GADGET is a light weight alternative - can have properties, enums and invokables. No signals and slots. Q_OBJECT sets up the needed tables for the introspection. 10
  • 11. QObject Example - Ownership class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) public: Person(QObject *parent=nullptr); Person(const QString &name, QObject *parent=nullptr); QString name() const; public slots: void setName(const QString &name); signals: void nameChanged(const QString &name); private: // ... }; Each QObject can have a parent. This is the object ownership tree. A parent destroys is children upon destruction. 11
  • 12. QObject Example - Signals and Slots class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) public: Person(QObject *parent=nullptr); Person(const QString &name, QObject *parent=nullptr); QString name() const; public slots: void setName(const QString &name); signals: void nameChanged(const QString &name); private: // ... }; Slots (callbacks) are ordinary methods placed in the public/protected/private slots sections. Signals (calls callbacks) are method signatures placed in the signals sections. The slots keyword is dropped by the pre-processor. The signals keyword is turned into protected by the the pre-processor. Q_INVOKABLE creates callables that are not setters. 12
  • 13. QObject Example - Properties class Person : public QObject { Q_OBJECT Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) public: Person(QObject *parent=nullptr); Person(const QString &name, QObject *parent=nullptr); QString name() const; public slots: void setName(const QString &name); signals: void nameChanged(const QString &name); private: // ... }; The policy since ancient times has been to create triplets: foo, setFoo, fooChanged. These can be further associated using the Q_PROPERTY macro. Great for QML / Javascript / Python integration! 13
  • 14. The Qt Meta Object Compiler *.h *.cpp moc moc_*.cpp compiler *.o linkerbinary Here goes the introspection data that enables “magic”. Sources Tools Intermediary Result 14
  • 15. QObject Connecting Person *person = new Person("Kalle"); QLabel *label = new QLabel(); connect(person, SIGNAL(nameChanged(QString)), label, SLOT(setText(QString))); connect(person, &Person::nameChanged, label, QLabel::setText); connect(person, &Person::nameChanged, [=] () { qDebug("Name changed!"); }); ● Use qOverload<signature>(function) to be specific (C++14) ● You can also connect signals to signals for propagation 15
  • 16. QObject Disconnecting Person *person = new Person("Kalle"); QLabel *label = new QLabel(); connect(person, SIGNAL(nameChanged(QString)), label, SLOT(setText(QString))); connect(person, &Person::nameChanged, label, QLabel::setText); connect(person, &Person::nameChanged, [=] () { qDebug("Name changed!"); }); disconnect(person, SIGNAL(nameChanged(QString)), label, SLOT(setText(QString))); disconnect(person, &Person::nameChanged, label, QLabel::setText); disconnect(person, 0, label, 0); person->disconnect(label); disconnect(person, &Person::nameChanged, 0, 0); person->disconnect(SIGNAL(nameChange(QString))); disconnect(person, 0, 0, 0); The anonymous lambda cannot be disconnected explicitly. 16
  • 17. Benefits of defining a main-loop ● Connections across threads ○ Depends on QMetaType system for serialization of arguments ○ Uses the thread affinity of each object, see QObject::thread ○ Makes connections asynchronous by default, but can be made blocking ■ connect(..., …, …, …, Qt::ConnectionType); ■ Can be auto, direct, queued, blocking-queued ■ Can also be unique ● The method QObject::deleteLater is useful for decoupling ○ Allows the whole call stack to complete prior to destroying an object ○ Can help simplify dependencies / reduce the number of needed callback points 17
  • 18. QObject and Observable ● QObject is a generic observable ● Each signal is a point to connect callbacks to ● Each slot is a potential callback ● Adds more run-time introspection, e.g. ○ names of things, property concept ○ Inheritance tree, list of available methods, etc ○ Nice for language bindings - not needed for C++ except in a very dynamic context 18
  • 19. Some words about boost ● Boost is free portable C++ library ● “establish ‘existing practice’ and provide reference implementations so that Boost libraries are suitable for eventual standardization” ● Peer-reviewed ● Kind of an incubator for new C++ library features 19
  • 20. The boost::signals2 library ● Signals2 library provides two fundamental object types ● Signal ○ boost::signals2::signal<void (float, int)> sig ● Connection ○ Boost::signals2::connect = sig.connect(boost::bind(<some signal handler func>) 20
  • 21. NewsProducer / NewsConsumer Example #include <boost/signals2/signal.hpp> class NewsProdcuer { public: using NewsUpdate = boost::signals2::signal<void (std::string)>; using NewsUpdateSubscriber = NewsUpdate::slot_type; NewsProdcuer() {} boost::signals2::connection connectSubscriber(const NewsUpdateSubscriber& subscriber) { return newsUpdate.connect(subscriber); } void publish(const std::string& news) { newsUpdate(news); } private: NewsUpdate newsUpdate; }; 21
  • 22. NewsProducer / NewsConsumer Example class NewsConsumer { public: NewsConsumer(const std::string& name, NewsProdcuer& producer) : m_consumerName(name) { m_newsProducerConnection = producer.connectSubscriber(boost::bind(&NewsConsumer::handleNewsUpdate, this, _1)); } ~NewsConsumer() { m_newsProducerConnection.disconnect(); } private: void handleNewsUpdate(const std::string update) { std::cout << m_consumerName << ": " << update << std::endl; } std::string m_consumerName; boost::signals2::connection m_newsProducerConnection; }; 22
  • 23. NewsProducer / NewsConsumer Example Usage: NewsProdcuer producer; NewsConsumer consumer1("Consumer 1", producer); NewsConsumer consumer2("Consumer 2", producer); producer.publish("News update"); Output: Consumer 1: News update Consumer 2: News update 23
  • 24. Some features of signals2 ● Signals2 can handle results from the different subscribers ● Signals can be blocked temporarily in a particular connection without disconnecting ○ I.e the slot will not be called even if the signal is emitted 24
  • 25. Handling results // aggregate_values is a combiner which places all the values returned // from slots into a container template<typename Container> struct aggregate_values { typedef Container result_type; template<typename InputIterator> Container operator()(InputIterator first, InputIterator last) const { Container values; while(first != last) { values.push_back(*first); ++first; } return values; } }; 25
  • 26. Handling results boost::signals2::signal<float (float, float), aggregate_values<std::vector<float> > > sig; sig.connect(&quotient); sig.connect(&product); sig.connect(&sum); sig.connect(&difference); std::vector<float> results = sig(5, 3); std::cout << "aggregate values: "; std::copy(results.begin(), results.end(), std::ostream_iterator<float>(std::cout, " ")); std::cout << "n"; 26
  • 27. Drawbacks of signals2 ● No automatic transfer of control from a sender of a signal to a receiver ● I.e if the work in a slot shall take place in another thread than the sender of the signal that thread switch needs to be implemented by the user. 27
  • 28. In boost::signals2 in conclusion ● Boost::signals2 provides a framework to implement signal/slot mechanism without needing to implement all the boilerplate oneself ● Not as flexible as QObject ● Not possible to transfer control between threads using signal/slots as in Qt 28
  • 29. The Synapse library ● Another signals/slot like library ● Submitted to boost for review but nothing has happened in the last 3 months… ● Very similar to boost::signals2 ● Have the ability to transfer control between threads 29
  • 30. Defining signals in Synapse and emitting them struct this_signal_; typedef this_signal_(*this_signal)(int); struct that_signal_; typedef that_signal_(*that_signal)(int); synapse::emit<that_signal>(5); 30
  • 31. Example (from the documentation) typedef struct clicked_(*clicked)(); class button { public: void click() { synapse::emit<clicked>(this); } }; 31
  • 32. Example (from the documentation) class dialog { public: void accept(); }; .... shared_ptr<button> emitter=make_shared<button>(); shared_ptr<dialog> receiver=make_shared<dialog>(); synapse::connect<clicked>(emitter, receiver, &dialog::accept); 32
  • 33. Synapse ● The emitter object can be any type. ● Signal types are not tied to the type of the emitter. ○ Signals can be added to existing types ● The author argues that since the signals are not tied to a type something like the MOC of Qt is not necessary ● The author argues that signals shall be held separate from the emitters. ● Provides a convenience object to implement transfer of control between threads: thread_local_queue 33
  • 36. Inter thread communication ● The thread_local_queue object has the following methods ○ Post ○ Poll ○ Wait ● Life-time of arguments needs to be managed explicitly, i.e. no serialization 36
  • 37. Inter thread communication ● Documentation suggests that posting on a thread_local_queue is handled automatically ● Probably the user needs to handle this is an slot/callback and post the events to the queue 37
  • 38. Synapse conclusions ● Signals2 seems more robust ● The thread_local_queue is a nice feature 38
  • 40. References ● Boost: https://www.boost.org/ ● Boost::signals2: https://www.boost.org/doc/libs/1_68_0/doc/html/signals2.html ● Synapse: https://zajo.github.io/boost-synapse/ ● Qt: https://www.qt.io/ 40