template<typename type_t>
class xtd::iobserver< type_t >
Provides a mechanism for receiving push-based notifications.
- Namespace
- xtd
- Library
- xtd.core
- Template Parameters
-
type_t | The object that provides notification information. This type parameter is contravariant. That is, you can use either the type you specified or any type that is less derived |
- Examples
- The following example illustrates the observer design pattern. It defines a
location
class that contains latitude and longitude information. struct location {
public:
location(double latitude, double longitude) : latitutde_(latitude), longitude_(longitude) {}
double latitude() const noexcept {return latitutde_;}
double longitude() const noexcept {return longitude_;}
private:
double latitutde_ = .0;
double longitude_ = .0;
};
The location_tracker
class provides the xtd::iobservable implementation. Its track_location
method is passed a nullable location
object that contains the latitude and longitude data. If the Location value is not nullopt
, the track_location
method calls the xtd::iobserver::on_next method of each observer. class location_tracker :
public iobservable<location> {
public:
location_tracker() = default;
if (find(observers_.begin(), observers_.end(), &observer) == observers_.end())
observers_.push_back(&observer);
}
auto iterator = find(observers_.begin(), observers_.end(), &observer);
if (iterator != observers_.end())
observers_.erase(iterator);
}
void track_location(optional<location> loc) {
for (auto observer : observers_) {
if (!loc.has_value())
observer->on_error(location_unknown_exception());
else
observer->on_next(loc.value());
}
}
void end_transmission() {
for (auto observer : observers_)
observer->on_completed();
observers_.clear();
}
private:
std::vector<iobserver<location>*> observers_;
};
Provides a mechanism for receiving push-based notifications.
Definition iobservable.hpp:155
Provides a mechanism for receiving push-based notifications.
Definition iobserver.hpp:154
If the location
value is nullopt
, the tack_location
method instantiates a location_unknown_exception
object, which is shown in the following example. It then calls each observer's on_error
method and passes it the location_unknown_exception
object. Note that location_unknown_exception
derives from xtd::exception, but does not add any new members. class location_unknown_exception :
public exception {
public:
location_unknown_exception() = default;
};
Defines the base class for predefined exceptions in the xtd namespace.
Definition exception.hpp:28
Observers subscribe to receive notifications from an location_tracker
object by calling its xtd::iobservable::subscribe method. And unsubscribe by calling its xtd::unobservable <type_t>::unsubscribe method. The location_tracker
class also includes an @ end_transmission method. When no further location data is available, this method calls each observer's xtd::iobserver::on_completed method, and then clears the internal list of observers.
In this example, the location_reporter
class provides the xtd::iobserver implementation. It displays information about the current location to the console. Its constructor includes a name
parameter, which allows the location_reporter
instance to identify itself in its string output. It also includes a subscribe
method, which wraps a call to the provider's xtd::iobservable::subscribe method. The location_reporter
class also includes an unsubscribe
method, to remove the subscription. The following code defines the location_reporter
class.
class location_reporter :
iobserver<location> {
public:
location_reporter(string name) : name_(name) {}
virtual ~location_reporter() {unsubscribe();}
string name() const noexcept {return name_;}
virtual void subscribe(iobservable<location>& provider) {
provider_ = &provider;
provider_->subscribe(*this);
}
void on_completed() noexcept override {
console::write_line("The location Tracker has completed transmitting data to {}.", name());
unsubscribe();
}
void on_error(const exception& e) noexcept override {
console::write_line("{}: The location cannot be determined.", name());
}
void on_next(const location& value) noexcept override {
console::write_line("{}: The current location is {}, {}", name(), value.latitude(), value.longitude());
}
virtual void unsubscribe() {
if (provider_ != nullptr) provider_->unsubscribe(*this);
provider_ = nullptr;
}
private:
string name_;
iobservable<location>* provider_ = nullptr;
};
The following code then instantiates the provider and the observer.
auto main() -> int {
location_tracker provider;
location_reporter reporter1 {"Fixed GPS"};
reporter1.subscribe(provider);
location_reporter reporter2 {"Mobile GPS"};
reporter2.subscribe(provider);
provider.track_location(location {47.6456, -122.1312});
reporter1.unsubscribe();
provider.track_location(location {47.6677, -122.1199});
provider.end_transmission();
}
constexpr null_opt nullopt
Represents a nullopt value. Used to indicate that an std::optional does not contain a value.
Definition nullopt.hpp:26
See You can show this example here
- Examples
- iobservable_iobserver.cpp.