delegates via boost::signals
От: Аноним  
Дата: 03.06.08 08:57
Оценка:
Была необходимость организовать колбэки связанные с некоторым ключем(в некотором роде событием) с небольшим набором операций: подписка\отписка по ключу, инициирование событий,создане новых событий.

Написал вот такую оболочку вокруг 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 не усмотрел готовое решение?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.