Created
May 3, 2025 03:48
-
-
Save DrkWithT/cb6d0bd07c0a00360a4317e3c98254df to your computer and use it in GitHub Desktop.
Attempt of Observer Pattern using CRTP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <unordered_map> | |
#include <print> | |
/// CRTP example for observer pattern | |
template <typename Derived> | |
class ObserverBase { | |
public: | |
ObserverBase() = default; | |
void update(int button_id) { | |
static_cast<Derived*>(this)->update(button_id); | |
} | |
}; | |
template <typename Derived> | |
class ControlBase { | |
public: | |
ControlBase() = default; | |
template <typename ObserverKind> | |
void set(ObserverKind* observer) noexcept { | |
static_cast<Derived*>(observer)->set(observer); | |
} | |
void notify() {} | |
}; | |
class ControlObserver : public ObserverBase<ControlObserver> { | |
private: | |
std::unordered_map<int, bool> m_control_states; // represents on or off switches... | |
void report() { | |
for (const auto& [id, state] : m_control_states) { | |
std::print("Switch {} is {}, ", id, state); | |
} | |
std::print("\n\n"); | |
} | |
public: | |
ControlObserver() | |
: m_control_states {} {} | |
void update(int control_id) { | |
m_control_states[control_id] = !m_control_states[control_id]; | |
report(); | |
} | |
}; | |
class ToggleControl : public ControlBase<ToggleControl> { | |
private: | |
ControlObserver* m_observer_ref; | |
int m_id; | |
public: | |
explicit ToggleControl(int id) noexcept | |
: m_observer_ref {nullptr}, m_id {id} {} | |
template <typename ObserverKind> | |
void set(ObserverKind* observer) noexcept { | |
m_observer_ref = observer; | |
} | |
void notify() { | |
if (!m_observer_ref) { | |
return; | |
} | |
m_observer_ref->update(m_id); | |
} | |
}; | |
int main() { | |
// Create fake UI observer... | |
ControlObserver toggle_sensor; | |
// Create fake UI controls (switches)... | |
ToggleControl toggler_1 {1}; // switch 1 | |
ToggleControl toggler_2 {2}; // switch 2 | |
// Register observer for fake controls... | |
toggler_1.set(&toggle_sensor); | |
toggler_2.set(&toggle_sensor); | |
toggler_1.notify(); // turn switch 1 on | |
toggler_1.notify(); // turn switch 1 off | |
toggler_2.notify(); // turn switch 2 on | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment