Using weak_ptr.lock() to remove observers when dead - c++

I am currently trying to implement the Observer pattern in a little game, using this as reference. Though, I am trying to implement a solution to one of the problems exposed in the chapter : how to prevent the subject from sending a notification to a removed observer ?
Instead of having simple pointers or owning the observers in the subject class (with a vector of shared_ptrs, simple pointers, or anything that implies owning the object), I thought that it could be good to have weak_ptrs (knowing that the observers are already instantiated using make_shared and shared_ptr). The primary use of this to me would be to be able to check if the observer is still alive with weak_ptr.lock() and to remove it if it isn't, but is this a good practice ? Does this implies other problems ?
Here's my (stripped down) code :
Main method :
int main() {
shared_ptr<Game> game = std::make_shared<Game>(); //Game extends subject
shared_ptr<Renderer> renderer = std::make_shared<Renderer>(); //Renderer extends observer
game.addObserver(renderer); //Automatic cast from shared_ptr to weak_ptr
}
Subject class :
class Subject {
public:
virtual void removeObserverAt(int index) {
m_observers.erase(m_observers.begin() + index);
}
protected:
virtual void notify(int objectID, Event ev, int64_t timestamp) {
int i = 0;
for(std::weak_ptr<Observer> obs : m_observers) {
if(auto sobs = obs.lock()) {
sobs->onNotify(objectID, shared_from_this(), ev, timestamp);
} else {
removeObserverAt(i);
}
i++;
}
}
private:
std::vector<std::weak_ptr<Observer>> m_observers;
};
Observer class :
class Observer {
public:
virtual ~Observer() {}
virtual void onNotify(int objectID, std::weak_ptr<Subject> caller, Event ev) = 0;
private:
};

Related

State Machine Change State

I'm continuously running into the same problem, and can't fix it even when looking through tutorials.
I've "set up" my State machine, but I can't transition between states.
Here is my StateMachine:
class StateMachine
{
State* m_State;
public:
StateMachine();
~StateMachine();
void changeState(State* state);
};
And here is an example State:
class A : State
{
public:
A();
~A();
void handleInput(int a);
}
If I pass a = 1 into A::handleInput() I want to transition to State B. But when I implement it I can't access the StateMachine from A::handleInput(), making me scrub my head in agony.
But when I implement it I can't access the StateMachine from A::handleInput()
Well, that's a well known problem with the State Pattern, that there's no mention how to keep the state classes in track with an enclosing State Machine.
IMO, that's one of the valid use cases to consider the StateMachine class as being implemented as a Singleton.
This way it's instance would be accessible from any Stateclass implementation.
As I'm talking in terms of Design Patterns here, the State classes could be designed with help of the Flyweight Pattern, since they're usually stateless themselves.
I've once driven all that into a c++ template framework, which abstracts the interfaces of State and State Machine (see link below).
Here's a short code example by these means:
StateMachine.h
struct State {
virtual void handleInput(int x) = 0;
virtual ~State() {} = 0;
};
class StateMachine {
State* m_State;
StateMachine();
public:
static StateMachine& instance() {
static StateMachine theInstance;
return theInstance;
}
void changeState(State* state) {
m_State = state;
}
void triggerInput(int x) {
m_State->handleInput(x);
}
};
StateA.h
#include "StateMachine.h"
class StateB;
extern StateB* stateB;
class StateA : public State {
public:
virtual ~StateA() {}
virtual void handleInput(int x) {
if(x == 1) {
// Change to StateB
StateMachine::instance.changeState(stateB);
}
else {
// Do something with x
}
}
};
I omit the definition od StateB here, should be the same manner as StateA.
References:
C++ Singleton Design Pattern
State machine template class framework for C++
I've taken a look at the Sourcemaking example and for me the implementation example really sucks; having to create new instances upon every state change:
https://sourcemaking.com/design_patterns/state/cpp/1
Personally as someone who's designed state machines in electronics with JK flip flops, I would use a similar but semantically different approach. The complexity in state machines involves the action performed according to the state and input; typically in C you would do this with lots of switch statements and possibly arrays describing how to handle the current state and new input aka event.
So to me the OO approach to this would be to model the event handler. This would have an interface which describes the format of the inputs. You then have different implementations of that interface for each different state. With that, the state machine can simply implement a collection of states to event handlers - array, vector or map. Although the handlers still may contain case statements, the overall spaghettiness is very much reduced. You can easily extend the design with new state handlers as and when necessary:
So you could have something like this:
#include <map>
typedef enum
{
//TODO : state list, e.g.
eOff,
eOn
}
teCurrentState;
typedef struct
{
//TODO : Add inputs here, e.g.
bool switch1;
}
tsInputDesc;
typedef struct
{
//TODO : Add outputs here, e.g.
bool relay1;
}
tsOutputDesc;
// ------------------------------------------------
class IEventHandler
{
public:
virtual ~IEventHandler() {}
// returns new state
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) = 0;
};
// ------------------------------------------------
class OnStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class OffStateHandler : public IEventHandler
{
public:
virtual teCurrentState handleInput(tsInputDesc const& input, tsOutputDesc& output) override
{
//TODO : IMPLEMENT
teCurrentState newState = TODO....
return (newState);
}
};
// ------------------------------------------------
class StateMachine
{
protected:
teCurrentState mCurrentState;
std::map<teCurrentState, IEventHandler*> mStateHandlers;
void makeHandlers()
{
mStateHandlers[eOff] = new OffStateHandler();
mStateHandlers[eOn] = new OnStateHandler();
}
public:
StateMachine()
{
makeHandlers();
mCurrentState = eOff;
}
void handleInput(tsInputDesc const& input, tsOutputDesc output)
{
teCurrentState newState = mStateHandlers[mCurrentState]->handleInput(input, output);
mCurrentState = newState;
}
};
// ------------------------------------------------
void runFsm()
{
StateMachine fsm;
tsInputDesc input;
tsOutputDesc output;
bool alive = true;
while (alive)
{
// TODO : set input according to....inputs (e.g. read I/O port etc)
fsm.handleInput(input, output);
// TODO : use output
}
}

Using weak_ptr to implement the Observer pattern

What I have so far is:
Observer.h
class Observer
{
public:
~Observer();
virtual void Notify() = 0;
protected:
Observer();
};
class Observable
{
public:
~Observable();
void Subscribe( std::shared_ptr<Observer> observer );
void Unsubscribe( std::shared_ptr<Observer> observer );
void Notify();
protected:
Observable();
private:
std::vector<std::weak_ptr<Observer>> observers;
};
Observer.cpp
void Observable::Subscribe( std::shared_ptr<Observer> observer )
{
observers.push_back( observer );
}
void Observable::Unsubscribe( std::shared_ptr<Observer> observer )
{
???
}
void Observable::Notify()
{
for ( auto wptr : observers )
{
if ( !wptr.expired() )
{
auto observer = wptr.lock();
observer->Notify();
}
}
}
(de/constructors are implemented here but empty, so I've left them out)
What I'm stuck on is how to implement the Unsubscribe procedure. I came across the erase - remove - end idiom, but I understand that it will not work "out of the box" with how I have setup my Observable. How do I inspect the weak_ptr elements in the observers vector such that I can remove the desired Observer?
I'm also looking for some advice on what the parameter type should be for my Un/Subscribe procedures. Would it be better to use std::shared_ptr<Observer>& or const std::shared_ptr<Observer>&, since we will not be modifying it?
I really do not want to have Observables owning their Observers, as it seems to betray the intentions of the pattern, and is certainly not how I want to structure the rest of the project that will ultimately be making use of the pattern. That said, an added layer of security / automation that I am considering is to have Observers store a mirror vector of weak_ptr. An Observer on its way out could then unsubscribe from all Observables it had subscribed to, and an Observable on its way out could erase the back-reference to itself from each of the Observers observing it. Evidently the two classes would be friends in such a scenario.
You can use std::remove_if with std::erase like this:
void Observable::Unsubscribe( std::shared_ptr<Observer> observer )
{
std::erase(
std::remove_if(
this->observers.begin(),
this->observers.end(),
[&](const std::weak_ptr<Observer>& wptr)
{
return wptr.expired() || wptr.lock() == observer;
}
),
this->observers.end()
);
}
You should indeed pass observer as const std::shared_ptr<Observer>&.
What I'm stuck on is how to implement the Unsubscribe procedure.
I suggest to store observers in a std::list because it's iterators are not invalidated on container modification. Then in subscribe in observer you store iterator to it and in unsubscribe you use the iterator to remove the element.
But of course you can use std::vector and std::remove_if as suggested in another answer.
Now about all that *_ptr stuff. In C++ RAII is your friend so use it. Get rid of public unsubscribe method. Instead observer must unsubscribe itself in it's destructor. This simplifies things very much: no more locking of weak pointers: if observer has been deleted, then it is not on the list. Just don't forget to protect observer list with a mutex if you have multithreaded application. If you use this design, then Observable would need only plain pointers to Observers and there will be no requirements how Observers must be stored.
class Observer {
public:
void subscribe(std::function<void()> unsubscribe) {
unsubscribe_ = std::move(unsubscribe);
}
virtual ~Observer() {
unsubscribe_();
}
private:
std::function<void()> unsubscribe_;
};
class Observable {
public:
void subscribe(Observer* observer) {
std::lock_guard<std::mutex> lock(observablesMutex_);
auto itr = observers_.insert(observers_.end(), observer);
observer->subscribe([this, itr]{
std::lock_guard<std::mutex> lock(observablesMutex_);
observers_.erase(itr);
});
}
private:
std::list<Observer*> observers_;
std::mutex observablesMutex_;
};
Note: for this code Observers must always be destroyed before the Observable.
Update: if you get more used to C++ lambdas you may find that having std::function as observer is more convenient in many cases than having a special class hierarchy. In this case you API can be like this:
class Handle {
public:
explicit Handle(std::function<void()> onDestroy)
: onDestroy_(std::move(onDestroy)) {}
Handle(const Handle&) = delete;
Handle(Handle&&) = default;
virtual ~Handle() {
onDestroy_();
}
private:
std::function<void()> onDestroy_;
};
class Observable {
public:
Handle subscribe(std::function<void()> observer) {
std::lock_guard<std::mutex> lock(observablesMutex_);
auto itr = observers_.insert(observers_.end(), observer);
return {[this, itr]{
std::lock_guard<std::mutex> lock(observablesMutex_);
observers_.erase(itr);
}};
}
private:
std::list<std::function<void()>> observers_;
std::mutex observablesMutex_;
};

Generic observer pattern in C++

In many cases in my application i need class A to register itself as a listener on class B to receive notification when something happens. In every case i define a separate interface B implements and A can call do. So for example, A will have the following method:
void registerSomeEventListener(SomeEventListener l);
Also, in many cases, B will need to support multiple listeners so i reimplement the registration and notifyAll logic.
One generic way i know is to have some EventListener (implement by A) and EventNotifier (implement by B) classes. In this case each event is identified by a string and A implements the method:
void eventNotified(string eventType);
I think this is not a good solution. It will result in many if-else statements in case A listens to several events and might result in bugs when event names are changed only in the listener or the notifier.
I wonder what is the correct way to implement the observer pattern in C++?
Take a look at boost::signals2. It provides a generic mechanism to define "signals" where other objects can register. The signal owner can then notify observers by "firing" the signal. Instead of register-methods, the subject defines signals as members which then keep track of connected observers and notify them when initiated. The signals are statically typed and accept every function with the matching signature. This has the advantage that there is no need for inheritance and thus a weaker coupling than the traditional observer inheritance hierarchy.
class Subject {
public:
void setData(int x) {
data_ = x;
dataChanged(x);
}
boost::signals2<void (int)> dataChanged;
private:
int data_;
};
class Observer {
public:
Observer(Subject& s) {
c_ = s.dataChanged.connect([&](int x) {this->processData(x);});
}
~Observer() {
c_.disconnect();
}
private:
void processData(int x) {
std::cout << "Updated: " << x << std::endl;
}
boost::signals2::connection c_;
};
int main() {
Subject s;
Observer o1(s);
Observer o2(s);
s.setData(42);
return 0;
}
In this example, the subject holds some int data and notifies all registered observers when the data is changed.
Lets say you have a generic event fireing object:
class base_invoke {
public:
virtual ~base_invoke () {};
virtual void Invoke() = 0;
}
But you want to fire events on different types of objects, so you derive from base:
template<class C>
class methodWrapper : public base_invoke {
public:
typedef void (C::*pfMethodWrapperArgs0)();
C * mInstance;
pfMethodWrapperArgs0 mMethod;
public:
methodWrapper(C * instance, pfMethodWrapperArgs0 meth)
: mInstance(instance)
{
mMethod = meth;
}
virtual void Invoke () {
(mInstance->*mMethod)();
}
}
Now if you create a wrapper for a collection of pointers to base_invoke you can call each fireing object and signal whichever method on whichever class you'd like.
You can also turn this collection class into a factory for the fireing objects. to simplyfy the work.
class Event {
protected:
Collection<base_invoke *> mObservers;
public:
// class method observers
template<class C>
void Add (C * classInstance, typename methodWrapper<C>::pfMethodWrapperArgs0 meth) {
methodWrapper<C> * mw = NEW(methodWrapper<C>)(classInstance, meth);
mObservers.Add(ObserverEntry(key, mw));
}
void Invoke () {
int count = mObservers.Count();
for (int i = 0; i < count; ++i) {
mObservers[i]->Invoke();
}
}
};
And your done with the hard work. Add an Event object anyplace you want listeners to subscribe. You'll probably want to expand this to allow removal of listeners, and perhaps to take a few function parameters but the core is pretty much the same.

vector of pointers to abstract class

I'm trying to implement the observer pattern in C++. What I attempting to do is to declare an observer interface with a single pure virtual method: notify(), and then let the the observers implement/derive that interface. Additionally, I want to keep a vector of pointers to all the observer classes in the observed class, so that I can call notify() on each of them. Sadly I'm having some trouble with the vector of pointers.
This is the observer interface:
class LocationEstimateObserver {
public:
virtual void notify() = 0;
};
I have two different classes implementing this interface. Hence, both implement the notify() method.
Here my observed class:
class Simulator {
public:
Simulator();
virtual ~Simulator();
void registerListener(LocationEstimateObserver& observer){observers_.push_back(&observer); };
void notifyObservers();
private:
std::vector<LocationEstimateObserver*> observers_;
};
And the observer class (implements the observer interface):
void InMapsEngine::startSimulation() {
Simulator sim();
sim.registerListener(*this);
}
And the Simulator.cpp file:
void Simulator::notifyObservers() {
for (unsigned int i = 0; i < observers_.size(); i++) {
observers_.at(i)->notify();
}
}
Now when I run the above code I get a segmentation fault. Could anyone of you point out what what I am doing wrong? I'm very new to C++.
EDIT: I just made a bizarre discovery: when I call observers_.size() it returns a very odd negative number, so the for loop fails. There lies the problem.
Why instead of adding instances of subclasses of LocationEstimateObserver, don't you have a vector of functions that will be notified when something will occur?:
Something like:
class Simulator {
public:
Simulator();
virtual ~Simulator();
void registerListener(const function<void()>& observer ) {observers_.push_back(observer); };
void notifyObservers();
private:
std::vector<function<void()>> observers_;
};
void observer1()
{
}
int main()
{
Simulator sim;
sim.registerListener(observer1);
}
And the Simulator.cpp file:
void Simulator::notifyObservers() {
for (auto& observer : observers_)
observer();
}
You keep a vector of pointers to objects that could have been deleted right after being registered. Make sure they are still there when you call Simulator::notifyObservers().

How to avoid downcast?

I have an implementation of a State Pattern where each state handles events it gets from a event queue. Base State class therefore has a pure virtual method void handleEvent(const Event*). Events inherit base Event class but each event contains its data that can be of a different type (e.g. int, string...or whatever). handleEvent has to determine the runtime type of the received event and then perform downcast in order to extract event data. Events are dynamically created and stored in a queue (so upcasting takes place here...).
I know that downcasting is a sign of a bad design but is it possible to avoid it in this case? I am thinking of Visitor Pattern where base class State would contain virtual handlers for each event but then again downcast will need to take place in the piece of code which dequeues event from a queue and passes it to the current state. (At least in this case big switch(eventID) would be only at one place...). Is Visitor Pattern the best way (best practice) to avoid downcasting?
Here is the pseudo-code (I am passing boost::shared_ptr in this example but downcasting happens anyway):
enum EventID
{
EVENT_1,
EVENT_2,
...
};
class Event
{
EventID id;
public:
Event(EventID id):id(id){}
EventID id() const {return id;}
virtual ~Event() = 0;
};
class Event1 : public Event
{
int n;
public:
Event1(int n):Event(EVENT_1), n(n){}
int getN() const {return n;}
};
class Event2 : public Event
{
std::string s;
public:
Event2(std::string s):Event(EVENT_2), s(s){}
std::string getS() const {return s;}
};
typedef boost::shared_ptr<Event> EventPtr;
class State
{
...
public:
...
virtual ~State() = 0;
virtual void handleEvent(const EventPtr& pEvent) = 0;
};
class StateA : public State
{
...
public:
void handleEvent(const EventPtr& pEvent)
{
switch(pEvent->id())
{
case EVENT_1:
int n = boost::static_pointer_cast<Event1>(pEvent)->getN();
...
break;
case EVENT_2:
std::string s = boost::static_pointer_cast<Event2>(pEvent)->getS();
...
break;
...
}
}
}
The typical visitor pattern performs no downcast, thanks to a double-dispatch strategy:
// Visitor.hpp
class EventBar;
class EventFoo;
class Visitor {
public:
virtual void handle(EventBar const&) = 0;
virtual void handle(EventFoo const&) = 0;
};
// Event.hpp
class Visitor;
class Event {
public:
virtual void accept(Visitor&) const = 0;
};
And the implementations:
// EventBar.hpp
#include <Event.hpp>
class EventBar: public Event {
public:
virtual void accept(Visitor& v);
};
// EventBar.cpp
#include <EventBar.hpp>
#include <Visitor.hpp>
void EventBar::accept(Visitor& v) {
v.handle(*this);
}
The key point here is that in v.handle(*this) the static type of *this is EventBar const&, which selects the correct virtual void handle(EventBar const&) = 0 overload in Visitor.
The idea of events is to pass detailed objects through generalized (and agnostic) interface.
Downcast is inevitable and part of the design. Bad or good, it's disputable.
Visitor pattern only hides the casting away from you. It's still performed behind the scenes, types resolved via virtual method address.
Because your Event already has the id, it's not completely agnostic of the type, so casting is perfectly safe. Here you're watching the type personally, in visitor pattern you're making compiler take care of that.
"Whatever goes up must go down".