signals.h

00001 /*   
00002  *   (c) Copyright 2008 Philipp Skadorov (philipp_s@users.sourceforge.net)
00003  *
00004  *   This file is part of FREESECS.
00005  *
00006  *   FREESECS is free software: you can redistribute it and/or modify
00007  *   it under the terms of the GNU General Public License as published by
00008  *   the Free Software Foundation, either version 3 of the License, or
00009  *   (at your option) any later version.
00010  *
00011  *   FREESECS is distributed in the hope that it will be useful,
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *   GNU General Public License for more details.
00015  *
00016  *   You should have received a copy of the GNU General Public License
00017  *   along with FREESECS, see COPYING.
00018  *   If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 #ifndef _SIGNALS_H
00021 #define _SIGNALS_H
00022 
00023 #include <vector>
00024 #include <algorithm>
00025 #include <functional>
00026 #include "callback.h"
00027 
00028 namespace freesecs
00029 {
00038     class signal_no_args_multiple_clients_t
00039     {
00040     public:
00041         template<class T>
00042         void add_handler(T *p_class, int(T::*p_func)())
00043         {
00044             _cbs.push_back(callback_t(p_class, p_func));
00045         }
00046         template<class T>
00047         void remove_handler(T *p_class, int(T::*p_func)())
00048         {
00049             if(!_cbs.empty())
00050             {
00051                 callback_t cb(p_class, p_func);
00052                 container_t::iterator it = 
00053                         find(_cbs.begin(), _cbs.end(), cb);
00054                 if(it != _cbs.end())
00055                 {
00056                     _cbs.erase(it);
00057                 }
00058             }
00059         }
00060         void operator()()
00061         {
00062             if(!_cbs.empty())
00063             {
00064                 for_each(_cbs.begin(), 
00065                          _cbs.end(), 
00066                          std::mem_fun_ref(&callback_t::operator()));
00067             }
00068         }
00069     private:
00070         typedef std::vector<callback_t> container_t;
00071         container_t _cbs;
00072     };
00073 
00082     class signal_no_args_single_client_t
00083     {
00084     public:
00085         template<class T>
00086         void add_handler(T *p_class, int(T::*p_func)())
00087         {
00088             _cb = callback_t(p_class, p_func);
00089         }
00090         template<class T>
00091         void remove_handler(T *p_class, int(T::*p_func)())
00092         {
00093         }
00094         void operator()()
00095         {
00096             _cb();
00097         }
00098     private:
00099         callback_t _cb;
00100     };
00101 
00102 
00111     template<class Arg>
00112     class signal_one_arg_multiple_clients_t
00113     {
00114     private:
00115         typedef std::vector< callback_1arg_t<Arg> > container_t;
00116     public:
00117         template<class T>
00118         void add_handler(T *p_class, int(T::*p_func)(const Arg&))
00119         {
00120             _cbs.push_back(callback_1arg_t<Arg>(p_class, p_func));
00121         }
00122         template<class T>
00123         void remove_handler(T *p_class, int(T::*p_func)(const Arg&))
00124         {
00125     /*        if(!_cbs.empty())
00126             {
00127                 callback_1arg_t<Arg> cb(p_class, p_func);
00128 
00129                 container_t::iterator it = 
00130                                 find(_cbs.begin(), _cbs.end(), cb);
00131                 if(it != _cbs.end())
00132                 {
00133                     _cbs.erase(it);
00134                 }
00135             }*/
00136         }
00137         void operator()(const Arg& arg)
00138         {
00139             if(!_cbs.empty())
00140             {
00141                 for_each(_cbs.begin(), 
00142                          _cbs.end(), 
00143                          functor_t<Arg>(arg));
00144             }
00145         }
00146     private:
00147         template<class T>
00148         class functor_t
00149         {
00150         public:
00151             functor_t(const T& t):_t(t){}
00152             void operator()(callback_1arg_t<T> &cb)
00153             {
00154                 cb(_t);
00155             }
00156         private:
00157             const T &_t;
00158         };
00159         container_t _cbs;
00160     };
00161 
00170     template<class Arg>
00171     class signal_one_arg_single_client_t
00172     {
00173     public:
00174         template<class T>
00175         void add_handler(T *p_class, int(T::*p_func)(const Arg&))
00176         {
00177             _cb = callback_1arg_t<Arg>(p_class, p_func);
00178         }
00179         template<class T>
00180         void remove_handler(T *p_class, int(T::*p_func)())
00181         {
00182         }
00183         void operator()(const Arg& arg)
00184         {
00185             _cb(arg);
00186         }
00187     private:
00188         callback_1arg_t<Arg> _cb;
00189     };
00190 
00191     #ifdef MULTIPLE_CLIENTS_FOR_SIGNAL
00192     #define signal_no_args_t signal_no_args_multiple_clients_t
00193     #define signal_one_arg_t signal_one_arg_multiple_clients_t
00194     #else
00195     #define signal_no_args_t signal_no_args_single_client_t
00196     #define signal_one_arg_t signal_one_arg_single_client_t
00197     #endif 
00199 }//namespace
00200 
00201 #endif 

Generated on Fri Oct 3 15:30:01 2008 for FREESECS hsms by  doxygen 1.5.1