Skip to content

Instantly share code, notes, and snippets.

@emadpres
Created July 6, 2019 22:47
Show Gist options
  • Save emadpres/062ea7169e5cd96efff51507f8369afd to your computer and use it in GitHub Desktop.
Save emadpres/062ea7169e5cd96efff51507f8369afd to your computer and use it in GitHub Desktop.
Observer Pattern - C++
// 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