A tight connection. Image by whologwhy (https://www.flickr.com/photos/hulagway/6020190512/)
Based on the signal class from the previous post we can implement a class which holds a value and notifies anyone who’s interested in value changes.
What’s the observer pattern?
[...] a software design pattern in which an object, called the subject, maintains a list of its dependants, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. - Wikipedia
So basically it allows for automatic notification event propagation whenever a value changed. Since these state change notifications work really well with the Vala Properties (and similarly with C# Properties), I’ll present a method how to implement something similar in C++.
The basic property template class
In its most basic form the Property template looks like the following. An instance of the template encapsulates a value which can be changed with the set() and get() methods. If the value is changed this way, the signal on_change() will be emitted.
Simple usage example
You can copy the above code and save it in a file named Property.hpp. Save this file in a directory together with the Signal template from the previous post. Save the ode below as main.cpp in the same directory.
You can compile the example with:
And if you execute the resulting application you will get the following output:
Improving the basic template class
There are several ways in which we can improve this template! First we will add a default constructor, then we will add stream operator support and then we will add the possibility to connect properties to another.
First of all, we can add a default constructor and some copy and move constructors. This is a little bit tricky, since the default constructor for built-in types does not initialize the value. This will cause problems because the value comparison in set() might fail if the value is not initialized. Therefore we need template specialisations for the default constructor! Let’s look at the code. First, replace the current constructor with the following list of constructors:
And put the following specialisations directly before the #endif preprocessor directive.
Now you can skip the initialization of the Integer property in the example above because the constructor will take care of this.
For convenience we will overload the stream operators for our template class. To do so, add the include #include <iostream> and put the following code directly before the #endif preprocessor directive.
Now we can do things like this:
Which will produce:
Connect properties amongst each other
This final change allows for data flow modelling. I won’t post the code here for it’s a little bit longer but you can download the final version of the class here. But I’ll show you an example of what’s possible with this class:
This will produce:
As you can imagine, it’s possible to do a lot of things here. There are numerous applications of these patterns and I really like the readability of the code. If you put these properties as members into classes the communication design becomes much easier and the class interface will be more intuitive.
Thank you for reading this code stuffed post but maybe you learned something! And if there are questions left feel free to ask!