5. Goals
● Lightweight
● No Dependencies
● Fast Runtime Performance
● Leverage the Compiler
● Decoupled, Flexible Design
● Properly Abstracted Events
● Inversion of Control
6. EventDemo: General Applications
● When you need to extend an existing eventdriven system with C++ components (i.e.
Node.js extensions)
● When you need to integrate existing C++
components in a decoupled manner
● When you need to demultiplex disparate
events (message brokers, sockets, IPC, IO,
etc) in a clean OO way
● Etc.
10. Example (single threaded)
void test1()
{
// Initialization
EventMgr &events = EventMgr::instance();
ConsumerAO consumer;
// Made to order
Hamburger hamb;
Coke coke;
// Deliver the order
events.notify( hamb );
events.notify( coke );
// Make another order
hamb.makePlain();
coke.size( 12 );
// Deliver
events.notify( hamb );
events.notify( coke );
// Eat up!
consumer.start();
}
11. Event Notification
void EventMgr::notify( unsigned int id, void *pEvent )
{
// Create an event that wraps the opaque pointer
Event e( id, pEvent );
for( EventListeners::iterator it = m_listeners.lower_bound( id );
it != m_listeners.upper_bound( id );
++it )
{
EventListener &l = *(it->second);
// For the demo code, this calls an EventBasedAO object
l.onEvent( e );
}
}
template< class T >
void EventMgr::notify( T &event )
{
// Call the TypeID utility function to get integer for type T
notify( TypeID< T >::id(), &event );
}
13. What about Event Subscription?
Trying to avoid code that looks like this:
Yes, we know it works, BUT...
14. C++ 11 To The Rescue
● Needed a better way to manage callbacks
○ With the variety of events, flexibility was key
○ Functions as first class objects? Not in C++ BUT we
can still manage them better
○ C++ 11 adds useful functor tools
● Note: Code samples are using the std::tr1
namespace. Due to (current) lack of
compiler support, we're using the Boost
library (included in the github project)
15. std::tr1::function
#include <functional>
#include <iostream>
struct Foo {
Foo(int num) : num_(num) {}
void print_add(int i) const { std::cout << num_+i << 'n'; }
int num_;
};
int main()
{
// store a call to a member function
std::tr1::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
Foo foo(314159);
f_add_display(foo, 1);
}
16. std::tr1::bind
#include <random>
#include <iostream>
#include <functional>
struct Foo {
void print_sum(int n1, int n2)
{
std::cout << n1+n2 << 'n';
}
};
int main()
{
// bind to a member function
Foo foo;
auto f3 = std::tr1::bind(&Foo::print_sum, foo, 95, _1);
f3(5);
}