#include <xtd/collections/generic/list>
#include <xtd/console>
#include <xtd/iobservable>
#include <xtd/iobserver>
#include <xtd/system_exception>
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;
};
public:
location_unknown_exception() {}
};
class location_tracker :
public iobservable<location> {
public:
location_tracker() = default;
if (std::find(observers_.begin(), observers_.end(), &observer) == observers_.end())
observers_.push_back(&observer);
}
auto iterator = std::find(observers_.begin(), observers_.end(), &observer);
if (iterator != observers_.end())
observers_.erase(iterator);
}
void track_location(std::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:
};
class location_reporter :
iobserver<location> {
public:
location_reporter(string name) : name_(name) {}
virtual ~location_reporter() {unsubscribe();}
string name() const noexcept {return name_;}
provider_ = &provider;
}
void on_completed() noexcept override {
console::write_line("The location Tracker has completed transmitting data to {}.", name());
unsubscribe();
}
void on_error(const std::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_;
};
auto main() -> int {
auto provider = location_tracker {};
auto reporter1 = location_reporter {"Fixed GPS"};
auto reporter2 = location_reporter {"Mobile GPS"};
reporter2.subscribe(provider);
provider.track_location(location {47.6456, -122.1312});
provider.track_location(location {47.6677, -122.1199});
provider.track_location(std::nullopt);
provider.end_transmission();
}
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Definition list.hpp:71
Provides a mechanism for receiving push-based notifications.
Definition iobservable.hpp:155
virtual void subscribe(iobserver< type_t > &observer) noexcept=0
Notifies the provider that an observer is to receive notifications.
virtual void unsubscribe(iobserver< type_t > &observer) noexcept=0
Notifies the provider that an observer no longer wants to receive notifications.
Provides a mechanism for receiving push-based notifications.
Definition iobserver.hpp:154
The exception that is thrown when a method call is invalid for the object's current state.
Definition system_exception.hpp:18
The xtd::collections::generic namespace contains interfaces and classes that define generic collectio...
Definition comparer.hpp:15
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.hpp:10