Created
July 6, 2019 22:47
-
-
Save emadpres/062ea7169e5cd96efff51507f8369afd to your computer and use it in GitHub Desktop.
Observer Pattern - C++
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
// Source: C++ Game Development Primer - Chapter 2 | |
#include <vector> | |
#include <algorithm> | |
#include <iostream> | |
/* | |
* Step 1: Generic Observer Pattern | |
*/ | |
template <typename Observer> | |
class Notifier { | |
using Observers = std::vector<Observer*>; | |
Observers m_observers; | |
public: | |
void Add(Observer *newObserver) | |
{ | |
assert(std::find(m_observers.begin(), m_observers.end(), newObserver)==m_observers.end()); | |
m_observers.emplace_back(newObserver); | |
std::cout << "Adding a new observer...\n"; | |
} | |
void Remove(Observer *toBeRemovedObserver) | |
{ | |
auto found = std::find(m_observers.begin(), m_observers.end(), toBeRemovedObserver); | |
if(found!= m_observers.end()) { | |
m_observers.erase(found); | |
std::cout << "Removing an observer...\n"; | |
} | |
} | |
template<void (Observer::*Method)()> | |
void Notify() | |
{ | |
for(auto o: m_observers) | |
(o->*Method)(); | |
} | |
}; | |
class QuitObserver { | |
public: | |
virtual void OnQuit() = 0; | |
}; | |
/* | |
* Step 2: Concrete Notifier (some class should be used <here> as its Observer type) | |
*/ | |
class QuitButton: public Notifier<QuitObserver> { | |
public: | |
void pressed() | |
{ | |
Notify<&QuitObserver::OnQuit>(); | |
} | |
}; | |
/* | |
* Step 3: Some class should implement Observer and subscribe to Notifier | |
*/ | |
class Game : public QuitObserver { | |
using QuitButtonPointer = std::shared_ptr<QuitButton>; | |
QuitButtonPointer m_quitButton { new QuitButton}; | |
void OnQuit() override | |
{ | |
std::cout<<"Quiting game ...\n"; | |
} | |
public: | |
Game(){ | |
m_quitButton.get()->Add(this); | |
m_quitButton->pressed(); | |
} | |
virtual ~Game(){m_quitButton.get()->Remove(this);} | |
}; | |
int main() | |
{ | |
auto g = Game(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment