System ten umożliwia w elastyczny sposób wykorzystać elementy programowania zdarzeniowego w dowolnej aplikacji, jest on swoją drogą częścią opracowywanego przeze mnie w wolnych chwilach frameworku.
Jego implementacja sprowadza się do jednego pliku nagłówkowego
cBaseEvent.h
#pragma once #include "stdafx.h" #include <boost/signal.hpp> #include <boost/bind.hpp> #include <boost/function.hpp> namespace Events { namespace Base { class _DLLExportCore cEventArgs { public: cEventArgs() { m_isValid = true; } virtual ~cEventArgs() { }; bool IsValid() const { return m_isValid; } private: bool m_isValid; }; class cEvent { typedef boost::signal<void (cEventArgs&)> TSignal; public: int GetNumSlots() const { return m_event.num_slots(); } void Invoke( cEventArgs& args = cEventArgs() ) { m_event( args ); } template<typename Class> void RegisterHandler (Class *t, void (Class::*FNMETHOD) ( cEventArgs& ) ) { m_event.connect(boost::bind( FNMETHOD, t,_1)); } template<typename Class> void UnregisterHandler (Class *t, void (Class::*FNMETHOD) ( cEventArgs& ) ) { m_event.disconnect(boost::bind( FNMETHOD, t,_1)); } void UnregisterAllHandlers() { m_event.disconnect_all_slots(); } private: TSignal m_event; }; } };
Przykład zastosowania:
class cArgs : public Events::Base::cEventArgs { public: cArgs( int a, int b ) { m_a = a; m_b = b; } void Print() { std::cout << "a="<<m_a<<" and b="<<m_b<<std::endl; } protected: int m_a; int m_b; }; Events::Base::cEvent myEvent1; class cA { public: void StartListeningForEvents() { myEvent1.RegisterHandler<cA>( this, &cA::OnMyEvent1); } void StopListeningForEvents() { myEvent1.UnregisterHandler<cA>( this, &cA::OnMyEvent1); } void OnMyEvent1( Events::Base::cEventArgs& a ) { cArgs& args = (cArgs&)a; a.Print(); } }; void main() { cA aa; aa.StartListeningForEvents(); cArgs args(4, 6); myEvent.Invoke(args); // will call OnMyEvent1, thus outputing 'a=4 and b=6' aa.StopListeningForEvents(); myEvent.Invoke(args); // event handler for this class was previously unregistered, this invoke will have no outcome }
#include „stdafx.h”
#include <boost/signal.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
namespace Events
{
namespace Base
{
class _DLLExportCore cEventArgs
{
public:
cEventArgs() { m_isValid = true; }
virtual ~cEventArgs() { };
bool IsValid() const { return m_isValid; }
private:
bool m_isValid;
};
class cEvent
{
typedef boost::signal<void (cEventArgs&)> TSignal;
public:
int GetNumSlots() const
{
return m_event.num_slots();
}
void Invoke( cEventArgs& args = cEventArgs() )
{
std::cout<<”invoke”<<std::endl;
size_t ns = m_event.num_slots();
m_event( args );
}
template<typename Class>
void RegisterHandler (Class *t, void (Class::*FNMETHOD) ( cEventArgs& ) )
{
std::cout<<”connect”<<std::endl;
m_event.connect(
boost::bind( FNMETHOD, t,_1));
}
template<typename Class>
void UnregisterHandler (Class *t, void (Class::*FNMETHOD) ( cEventArgs& ) )
{
std::cout<<”dissconnect”<<std::endl;
m_event.disconnect(
boost::bind( FNMETHOD, t,_1));
}
void UnregisterAllHandlers()
{
std::cout<<”disconnect_all_slots”<<std::endl;
m_event.disconnect_all_slots();
}
private:
TSignal m_event;
};
}
};#pragma once
#include „stdafx.h”
#include <boost/signal.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
namespace Events
{
namespace Base
{
class _DLLExportCore cEventArgs
{
public:
cEventArgs() { m_isValid = true; }
virtual ~cEventArgs() { };
bool IsValid() const { return m_isValid; }
private:
bool m_isValid;
};
class cEvent
{
typedef boost::signal<void (cEventArgs&)> TSignal;
public:
int GetNumSlots() const
{
return m_event.num_slots();
}
void Invoke( cEventArgs& args = cEventArgs() )
{
std::cout<<”invoke”<<std::endl;
size_t ns = m_event.num_slots();
m_event( args );
}
template<typename Class>
void RegisterHandler (Class *t, void (Class::*FNMETHOD) ( cEventArgs& ) )
{
std::cout<<”connect”<<std::endl;
m_event.connect(
boost::bind( FNMETHOD, t,_1));
}
template<typename Class>
void UnregisterHandler (Class *t, void (Class::*FNMETHOD) ( cEventArgs& ) )
{
std::cout<<”dissconnect”<<std::endl;
m_event.disconnect(
boost::bind( FNMETHOD, t,_1));
}
void UnregisterAllHandlers()
{
std::cout<<”disconnect_all_slots”<<std::endl;
m_event.disconnect_all_slots();
}
private:
TSignal m_event;
};
}
};