AnCH Framework  0.1
Another C++ Hack Framework
AnCH events library documentation

Table of Contents

Introduction

AnCH events library aims to provide event programming facilities based on C++11 thread library.
It is based on C++ template. This is not a library but only header files.

This library is based on observer/observable design pattern. So the base classes are anch::events::Observer<T> and anch::events::Observable<T>.

Prerequisites

Installation

TODO fill this section

Conception

AnCH events library is header files only. So you don't need to link to library.

Observer/Observable

These are the AnCH events library main classes. These classes are template classes.
Specialization concerns the event type that observer and observable can manage. An Observable<type> can be observe by any Observer<type>.

Observer is pure virtual. The only method which has to be implemented is Observer<type>::notify(const type&).
Observers have to register and unregister themself to observable(s) by calling methods Observable<type>::addObserver(Observer<type>) and Observable<type>::removeObserver(Observer<type>). Each observable maintains an observers list to notify them.

Observable is fully implemented and ready to use. To notify observers, call method Observable<type>::notifyObservers(const type&).

Event handler

EventHandler is a template that aims to provide a way to inherits multiple times from Observer.
This class is based on the C++ curiously recurring pattern. Template parameters will be event type and observer implementation type. It implements the Observer<type>::notify(const type&) by calling the callback method passed as argument in constructor.

EventHandler provides also a simple way to register the observer in global event management (see Event bus) through its constructors.

EventHandler may need EventBus: in order to initialize EventBus, you will have to call INIT_ANCH_EVENT_BUS macro somewhere in your source file.

Event bus

EventBus provides a way to fire events in global way.
Methods are the same than Observable.
Every methods can be accessed in static or instance way. The static method are named similar to instance method with the first letter in upper case. You should use the instance because the static will always retrieved the EventBus instance through mutex.

EventBus has an additional method compare to Observable: scheduleDeferred which allow to put an event in a queue which will be dequeued later in another thread.

In order to initialize EventBus, you will have to call INIT_ANCH_EVENT_BUS macro somewhere in your source file.

Examples

You can read unitary tests in the test directory to have some other code example.

Observer/Observable

#include "events/observable.hpp"
#include "events/observer.hpp"
#include <iostream>
class StrObserver: public anch::events::Observer<std::string> {
void notify(const std::string& event) noexcept {
std::cout << event << std::endl;
}
};
int main(void) {
StrObserver obs;
strObservable.addObserver(obs);
strObservable.notifyObservers("test");
strObservable.removeObserver(obs);
return 0;
}

Event handler

#include "events/eventHandler.hpp"
#include "events/observable.hpp"
INIT_ANCH_EVENT_BUS;
#include <iostream>
class Type1 {
private:
std::string _message;
public:
Type1(const std::string& message): _message(message) { }
inline const std::string& getMessage() const {
return _message;
}
};
template<typename Derived>
class Type1EventHandlerIface: public anch::events::EventHandler<Type1,Derived> {
public:
Type1EventHandlerIface(): anch::events::EventHandler<Type1,Derived>(&Derived::onType1) { }
virtual void onType1(const Type1& event) = 0;
};
class Type2 {
private:
int _index;
public:
Type2(int index): _index(index) { }
inline int Index() const {
return _index;
}
};
template<typename Derived>
class Type2EventHandlerIface: public anch::events::EventHandler<Type2,Derived> {
public:
Type2EventHandlerIface(): anch::events::EventHandler<Type2,Derived>(&Derived::onType2) { }
virtual void onType2(const Type2& event) = 0;
};
class TypesEventHandler: public Type1EventHandlerIface<TypesEventHandler>, public Type2EventHandlerIface<TypesEventHandler> {
public:
TypesEventHandler(): Type1EventHandlerIface<TypesEventHandler>(), Type2EventHandlerIface<TypesEventHandler>() { }
virtual void onType1(const Type1& event) override {
std::cout << "Type1: " << event.getMessage() << std::endl;
}
virtual void onType2(const Type2& event) override {
std::cout << "Type2: " << event.Index() << std::endl;
}
};
int main(void) {
TypesEventHandler handler;
obs1.addObserver(handler);
obs2.addObserver(handler);
obs1.notifyObservers(Type1("test"));
obs2.notifyObservers(Type2(1));
return 0;
}

Event bus

#include "events/eventHandler.hpp"
#include "events/observable.hpp"
INIT_ANCH_EVENT_BUS;
#include <iostream>
class Type1 {
private:
std::string _message;
public:
Type1(const std::string& message): _message(message) { }
inline const std::string& getMessage() const {
return _message;
}
};
template<typename Derived>
class Type1EventHandlerIface: public anch::events::EventHandler<Type1,Derived> {
public:
Type1EventHandlerIface(): anch::events::EventHandler<Type1,Derived>(&Derived::onType1) { }
virtual void onType1(const Type1& event) = 0;
};
class Type2 {
private:
int _index;
public:
Type2(int index): _index(index) { }
inline int Index() const {
return _index;
}
};
template<typename Derived>
class Type2EventHandlerIface: public anch::events::EventHandler<Type2,Derived> {
public:
Type2EventHandlerIface(): anch::events::EventHandler<Type2,Derived>(&Derived::onType2) { }
virtual void onType2(const Type2& event) = 0;
};
class TypesEventHandler: public Type1EventHandlerIface<TypesEventHandler>, public Type2EventHandlerIface<TypesEventHandler> {
public:
virtual void onType1(const Type1& event) override {
std::cout << "Type1: " << event.getMessage() << std::endl;
}
virtual void onType2(const Type2& event) override {
std::cout << "Type2: " << event.Index() << std::endl;
}
};
int main(void) {
TypesEventHandler handler;
return 0;
}