Getting started¶
The library has a few classes and a set of macros and function overloads:
- subject<void(Args …)>
- Provides a way to notify subscribed observers when an event occurs.
- value<T>
- Holds value types and provides a way to notify subscribed observers when the value changes.
- OBSERVABLE_PROPERTIES and observable_property
- Values nested inside an enclosing class with setters accessible only from inside that class.
- observe()
- A group of overloaded functions that can create observable values that are updated when their argument expression changes.
Getting started with subjects¶
Subjects are the simplest observable objects. They provide a way to get notified when some event occurs.
#include <iostream>
#include <string>
#include <observable/observable.hpp>
using namespace std;
using namespace observable;
// Will print "Hello {name}" each time you enter a name.
// Type exit to stop.
int main()
{
auto name_entered = subject<void(string)> { };
// Subscribe to name_entered notifications.
name_entered.subscribe([](auto const & name) {
cout << "Hello "s
<< name
<< "!"s
<< endl;
});
while(cin)
{
cout << "What's your name?"s << endl;
// Read the name.
auto input_name = string { };
cin >> input_name;
if(input_name.empty() || input_name == "exit"s)
break;
// Notify all name_entered observers.
name_entered.notify(input_name);
}
return 0;
}
Getting started with values¶
Values are wrappers around value-types. You can subscribe to changes to the contained value-type.
The observe()
functions can be used to generate values associated with
an expression. For example: auto result = observe((a + b) / 2.0)
.
The result
value will recompute the average, each time either the a
or b
value changes.
#include <iostream>
#include <string>
#include <observable/observable.hpp>
using namespace std;
using namespace observable;
// Will print "Hello {name}" each time you enter a name.
// Type exit to stop.
int main()
{
auto name = value<string> { };
// Recompute the greeting each time name changes and
// fire change notifications.
auto greeting = observe("Hello "s + name + "!"s);
// Subscribe to greeting changes.
greeting.subscribe([](auto const & hello) {
cout << hello << endl;
});
while(cin)
{
cout << "What's your name?"s << endl;
// Read the name.
auto input_name = string { };
cin >> input_name;
if(input_name.empty() || input_name == "exit"s)
break;
// Update the name value.
name = input_name;
}
return 0;
}
Getting started with observable properties¶
Properties are just values that are nested inside a class. This makes all setters inaccessible from outside the enclosing class.
#include <iostream>
#include <string>
#include <observable/observable.hpp>
using namespace std;
using namespace observable;
// Will print "Hello {name}" each time you enter a name.
// Type exit to stop.
// Greet people using names read from stdin.
class Greeter
{
OBSERVABLE_PROPERTIES(Greeter)
public:
// Current name.
observable_property<string> name;
// Current greeting.
observable_property<string> greeting = observe(
"Hello "s + name + "!"s
);
public:
// Read names from stdin until the user quits.
void read_names()
{
while(cin)
{
cout << "What's your name?"s << endl;
auto input_name = string { };
cin >> input_name;
if(input_name.empty() || input_name == "exit"s)
break;
name = input_name;
}
}
};
int main()
{
Greeter greeter;
// Print the greetings.
greeter.greeting.subscribe([](auto const & hello) {
cout << hello << endl;
});
// Properties cannot be set from outside the class. The
// line below will not compile:
// greeter.name = input_name;
greeter.read_names();
return 0;
}