88 lines
No EOL
1.9 KiB
C++
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;
|
|
} |