trainings/CreatingReliableSoftwareCpp/Presentation/examples/observer/observer2.cpp

88 lines
No EOL
1.9 KiB
C++

#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <memory>
#include <vector>
template <typename State>
struct Observer {
virtual ~Observer() = default;
virtual void update(State state) = 0;
};
class Browser {
public:
enum class State {
Closing,
FocusChanged
};
using BrowserObserver = Observer<State>;
~Browser() {
std::cout << "Browser is closing\n";
notify(State::Closing);
std::cout << "Browser closed\n";
}
// Rule of 5 :)
void attach(BrowserObserver* observer) { _observers.push_back(observer); }
void detach(BrowserObserver* observer) { std::erase(_observers, observer); }
private:
void notify(State state) const {
std::ranges::for_each(_observers, [state](auto* observer) {
observer->update(state);
});
}
std::vector<BrowserObserver*> _observers;
};
class TabStripManager : public Browser::BrowserObserver {
public:
TabStripManager(Browser* browser)
: _browser(browser) {
assert(browser);
browser->attach(this);
}
~TabStripManager() {
if (_browser) {
_browser->detach(this);
}
}
// Rule of 5 :)
// dispatch message
void update(Browser::State state) override {
switch (state) {
case Browser::State::Closing: {
browserAboutToQuit();
return;
}
case Browser::State::FocusChanged: {
browserFocusChanged();
return;
}
}
}
private:
void browserAboutToQuit() {
std::cout << "TabStripManager will close tabs\n";
_browser = nullptr;
}
void browserFocusChanged() {
std::cout << "TabStripManager lost focus\n";
}
Browser* _browser;
};
int main() {
std::unique_ptr<Browser> browser = std::make_unique<Browser>();
TabStripManager manager(browser.get());
browser = nullptr;
}