What is the simplest Event design pattern - c++

Lately, I've been pondering about the following problem for a while. For the code bellow, what is the easiest way to modify Game::counter via Event::Perform() method which is called from Game class?
I considered Observer and Command design patterns, but it seems that there is a much simpler way to do this.
class Game
{
public:
Game();
private:
int counter;
vector<Event*> Events;
};
class Event
{
public:
virtual void Perform() = 0;
};
Thank you

Directly from Perform, none. counter is private, so it can only be accessed by Game, as part of one of the functions of the interface it provides.
Calling this function is then just a matter of having access to the right Game instance. You can pass that one as a parameter to Perform:
virtual void Perform(Game &) = 0;
... or inject it into derived Events:
struct MyEvent : Event {
MyEvent(Game &game) : _game{&game} { }
void Perform() const override {
// Do something with *game
}
private:
Game *_game;
};
Since I guess we are talking about the Events referenced by Game::Events, which Game itself will process, the parameter looks like the most cohesive approach.

Related

Can I make use on templates when implementing different interfaces in the same way?

I have many interfaces for different listeners, the all look like this:
class ListenerA
{
public:
virtual void
onEventA(const EventA&) = 0;
};
class ListenerB
{
public:
virtual void
onEventB(const EventB&) = 0;
};
When testing, I always end up just collecting those events in a std::vector for analyzing them afterwards in a specific test suite. Those event collectors all look the same like this one for example:
class EventACollector : public ListenerA
{
public:
const auto&
events() const
{
return m_events;
}
private:
void
onEventA(const EventA& event) override
{
m_events.emplace_back(event);
}
std::vector<EventA> m_events;
};
Is there a way to template an EventTCollector, so that I do not have to write it every time? Given that the virtual function name does change for every listeners?
C++ does not have introspection, so you cannot find the virtual function in ListenerA. The other parts can go in a templated base class, but the override you'll need to define manually.
Modern C++ would use a std::function<void(EventA)> instead of a named interface, but that won't help you as a user of that old interface.

Override a method when creating an object in Arduino/C++

I am working on a C++ Arduino sketch that creates a GUI on an OLED display. I want to have buttons buttons that all do different things when you press them. In Java, I can simply override the method when creating an anonymous class like this:
class Example {
public void method() {
}
}
Example e = new Example() {
#Override
public void method() {
//do something
}
};
So my question is: Can I do this in an C++?
As arduino sketch are in fact C/C++, you could do the same as in Java.
class Button {
virtual void push() = 0;
}
class PowerButton : public Button {
virtual void push() {
shutdown();
}
}
Notice the virtual keyword, it's used to declare a method overidable, the "= 0" means pure virtual (the address of the method is 0). It simply says that this method is not implemented in this class, the class became abstract as in Java.
Also, the virtual keyword is not mandatory, but if you don't put it, C++ will just call the method of the given type and not from the real type.
Take a look there
But, the difference with Java is that you can't create an anonymous class directly in the code. Instead, maybe take a look for lambda.
For example, the class Button would became :
class Button {
public:
Button(const std::function<void()> &pushCallback) :
mPushCallback(pushCallback) {}
void push() { mPushCallback(); }
private:
const std::function<void()> mPushCallback;
And then the usage:
Button powerButton([]() {
powerOff();
});
Brackets are use to "capture" a variable, for example this, &str { myMethodInMyClass(str); }
Parenthesis are used to pass parameters
The std::function class take the function type as type parameter, a function that take a string as const ref and an int and that return an int will look like this : std::function<int(const std::string &, int)>

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().

Dependency injection and event handling

class ITransportProvider
{
public:
virtual ~ITransportProvider() { }
protected:
virtual void SendData() = 0;
// Concrete TransportProvider will call OnReceiveDataEvent
// virtual void RegisterHandlers(std::function<void()> onReceiveDataEvent);
}
class Device
{
public:
Device(shared_ptr<ITransportProvider> transport)
: m_Transport(transport)
{
// transport->RegisterHandlers(boost::bind(&Device::OnReceiveData, this));
}
void SendData()
{
m_Transport->SendData();
}
// Which design pattern to use to get concrete TransportProvider's OnReceiveData event?
//void OnReceiveData()
//{
//}
private:
shared_ptr<ITransportProvider> m_Transport;
};
I've always added a "RegisterHandlers" in my ITransportProvider and make Device call it in its c'tor.
I'd like to know if its correctness in the eyes of DI/IoC gurus and would love to hear all suggestions.
EDIT:
To clarify, I'm asking if there's a better way of decoupling TransportProvider from Device besides the above way which is via DI and the Observer pattern.
You have a reasonable design. Decoupling can be handled at many different levels in different ways with various trade-offs. Your design is good for the case where you know the sending and receiving are related, but there is no particular compile-time relationship between Device instances and Transport implementations. If there was a compile-time relationship, you might use policy-based design:
class TransportProviderA
{
public:
void SendData();
virtual void OnReceiveData() = 0;
}
template <typename TransportPolicy>
class Device : public TransportPolicy
{
public:
Device(const TransportPolicy &transport_policy)
: TransportPolicy(transport_policy)
{
}
// SendData provided by TransportPolicy
virtual void OnReceiveData(); // overrides TransportPolicy's template method.
};
Then use it like this:
Device<TransportPolicyA> my_device(TransportPolicyA());

How to access class members from a method?

I want to access the engine from inside my eventReceiver object. They are fellow members of the game class, but how do I reach it?
// game.h
class game
{
public:
game();
3dEngine* engine;
eventReceiver* receiver;
};
// eventReceiver.h
class eventReceiver
{
public:
eventReceiver () {}
virtual bool OnEvent (const SEvent& event)
{
...
case QUIT_BUTTON_PRESSED:
>>> engine->quit(); // how to access engine from here??
return true;
...
}
};
Should I use 'this' ? I don't understand why receiver can't see the engine.
Implement the class as a Singleton and write a getter for the engine property. Accessing code could then look like:
game::getInstance()->getEngine()->quit();
I would recommend you though, that you create a quite() method in the game class itself hiding implementation details and allowing you to handle overall application shutdown and not just of the 3dEngine:
game::getInstance()->quit();
If you dont want to implement the game class as singleton you could also pass a reference/pointer of a game object to the constructor of your event handler:
class CloseButtonHandler : public eventHandler {
game& game;
public:
CloseButtonHandler(game& game) : game(game) {
}
virtual bool OnEvent(const SEvent& event){
...
game.getEngine()->quit();
}
}
The eventReceiver shouldn't know anything about the engine. That's a bad design. There are a few solutions. One reasonable solution is to derive game from eventReceiver since game can clearly receive events. You can then implement the game-specific OnEvent handler in game itself. From there you can call engine->quit.
I don't know how elegant this design is, but it works.
I just separated the receiver from the game class and gave its constructor a pointer to the instance of myGame. (Thanks to Paranaix)
class eventReceiver {
public:
eventReceiver (game* gameInstance) : gamei(gameInstance)
virtual bool OnEvent (...)
{...
case QUIT_BUTTON_PRESSED:
gamei.engine->quitGame();
...}
private:
game* gamei;
}
int main() {
game myGame;
eventReceiver receiver (&myGame);
}