Hay, I wanted to clear my head on the topic of C++ events. There's sigslot, boost::signal, etc. I would still want to wrap any of those so it would be easier for myself to navigate/modify. So I came up with this example to try and weed it out. Trying to figure out the best way to propagate up events.
Does anybody have any comments, criticisms or improvements?
I wonder if the syntax could get any easier. I'm not fond of having to use boost::bind in the syntax with _1, but I guess that's the only way it could work in C++. At least, without macros?
Thanks
This code should run.
Skip to main():
Code:
#include <iostream>
#include <vector>
#include <boost/bind.hpp>
#include <boost/function.hpp>
namespace Framework
{
template<typename T>
class Event
{
private:
std::vector<T> list;
public:
template<typename A1>
Event<T>& operator()(A1& a1)
{
//std::cout << &list << ": Should be bigger than zero: " << this->list.size() << std::endl;
for(std::vector<T>::const_iterator i = this->list.begin(), l = this->list.end(); i != l; ++i)
{
(*i)(a1);
}
return *this;
}
Event<T>& operator+(T& t)
{
//std::cout << &list << ": Increased" << std::endl;
this->list.push_back(t);
return *this;
}
Event<T>& operator+=(T& t)
{
return this->operator+(t);
}
template<typename A>
Event<T>& operator+=(A& a)
{
return this->operator+(T(a));
}
};
}
class Table
{
public:
typedef Framework::Event<boost::function1<void, Table> > Event;
Event ChangeEvent;
// example
void UpdateSomething()
{
this->ChangeEvent(*this);
}
public:
unsigned int id;
};
class Site
{
public:
typedef Framework::Event<boost::function1<void, Site> > Event;
Table::Event AddTableEvent;
Table::Event ChangeTableEvent;
Site()
{
}
// example
Table UpdateSomething()
{
Table table;
table.id = 1;
table.ChangeEvent += this->ChangeTableEvent; // attach event handlers
this->AddTableEvent(table);
return table;
}
};
class Application
{
public:
Site::Event AddSiteEvent;
Site::Event ChangeSiteEvent;
// example
Site UpdateSomething()
{
Site site;
site.AddTableEvent += boost::bind(&Application::OnAddTable, this, _1);
site.ChangeTableEvent += boost::bind(&Application::OnChangeTable, this, _1);
return site;
}
/*
* Callbacks
*/
void OnAddTable(Table& table)
{
std::cout << "Added: " << table.id << std::endl;
}
void OnChangeTable(Table& table)
{
std::cout << "Changed: " << table.id << std::endl;
}
};
int main(int argc, char* argv[])
{
Application app;
Site& site = app.UpdateSomething();
Table& table = site.UpdateSomething();
table.UpdateSomething();
std::cout << "End" << std::endl;
std::cin.get();
return 0;
}
Output: