Была необходимость организовать колбэки связанные с некоторым ключем(в некотором роде событием) с небольшим набором операций: подписка\отписка по ключу, инициирование событий,создане новых событий.
Написал вот такую оболочку вокруг boost::signals
template <class FuncSignature, class Key=int>
class CallbackManager
{
public:
typedef typename boost::signal<FuncSignature> signal_type;
typedef boost::shared_ptr<signal_type> signal_ptr;
typedef typename signal_type::slot_function_type callback_type;
typedef boost::signals::connection connection_type;
typedef Key id_type;
typedef std::map<id_type,signal_ptr> callback_map_type;
public:
void register_event(const id_type id);
connection_type add_callback(const id_type event_id, callback_type clb);
//для 0 аргументов
void fire_event(const id_type id);
//для 1 аргумента
template<class A1>
void fire_event(const id_type id,const A1&);
//для Х аргументов можно продолжать до посинения...
void del_callback(connection_type& item);
private:
callback_map_type _callbacks;
};
template <class FuncSignature,class Key>
void CallbackManager<FuncSignature,Key>::fire_event( const id_type id )
{
(*_callbacks[id])();
}
template <class FuncSignature, class Key>
template<class A1>
void CallbackManager<FuncSignature, Key>::fire_event( const id_type id,const A1& arg1)
{
return (*_callbacks[id])(arg1);
}
template <class FuncSignature, class Key>
void CallbackManager<FuncSignature, Key>::del_callback(connection_type& item )
{
item.disconnect();
}
template <class FuncSignature,class Key>
typename CallbackManager<FuncSignature,Key>::connection_type CallbackManager<FuncSignature,Key>::add_callback( const id_type event_id,callback_type clb )
{
return (*_callbacks[event_id]).connect(clb);
}
template <class FuncSignature,class Key>
void CallbackManager<FuncSignature,Key>::register_event( const id_type id )
{
_callbacks.insert(std::make_pair(id, new signal_type));
}
из очевидных недароботок вижу:
1. в попыхах не реализован возврат значений
2. если обьект-слот умер, то во время его "сигнализации" будет беда(возможности boost::trackable пока отложим)
3. для разных сингатур колбэков нужно инстанциировать разные менеджеры, но в рамках моей задачи это удовлетворяет.
Возникает ряд вопросов:
1. не изобрел ли я большой велосипед?
2. целесообразен ли вышеописанный код, возможно в самих signal.hpp не усмотрел готовое решение?