sigslot的动态模板版本
来源:互联网 发布:dos下mac地址烧录工具 编辑:程序博客网 时间:2024/04/27 16:32
拿到一个简单好用的库,但是里面使用了以前不支持动态模板的做法,写了很多重复代码。我用动态模板改进了一下,减少代码量。
原代码地址:http://sigslot.sourceforge.net/
// sigslot.h: Signal/Slot classes// // Written by Sarah Thompson (sarah@telergy.com) 2002.//// License: Public domain. You are free to use this code however you like, with the proviso that// the author takes on no responsibility or liability for any use.//// QUICK DOCUMENTATION ////(see also the full documentation at http://sigslot.sourceforge.net/)////#define switches//SIGSLOT_PURE_ISO- Define this to force ISO C++ compliance. This also disables// all of the thread safety support on platforms where it is // available.////SIGSLOT_USE_POSIX_THREADS- Force use of Posix threads when using a C++ compiler other than// gcc on a platform that supports Posix threads. (When using gcc,// this is the default - use SIGSLOT_PURE_ISO to disable this if // necessary)////SIGSLOT_DEFAULT_MT_POLICY- Where thread support is enabled, this defaults to multi_threaded_global.// Otherwise, the default is single_threaded. #define this yourself to// override the default. In pure ISO mode, anything other than// single_threaded will cause a compiler error.////PLATFORM NOTES////Win32- On Win32, the WIN32 symbol must be #defined. Most mainstream// compilers do this by default, but you may need to define it// yourself if your build environment is less standard. This causes// the Win32 thread support to be compiled in and used automatically.////Unix/Linux/BSD, etc.- If you're using gcc, it is assumed that you have Posix threads// available, so they are used automatically. You can override this// (as under Windows) with the SIGSLOT_PURE_ISO switch. If you're using// something other than gcc but still want to use Posix threads, you// need to #define SIGSLOT_USE_POSIX_THREADS.////ISO C++- If none of the supported platforms are detected, or if// SIGSLOT_PURE_ISO is defined, all multithreading support is turned off,// along with any code that might cause a pure ISO C++ environment to// complain. Before you ask, gcc -ansi -pedantic won't compile this // library, but gcc -ansi is fine. Pedantic mode seems to throw a lot of// errors that aren't really there. If you feel like investigating this,// please contact the author.//////THREADING MODES////single_threaded- Your program is assumed to be single threaded from the point of view// of signal/slot usage (i.e. all objects using signals and slots are// created and destroyed from a single thread). Behaviour if objects are// destroyed concurrently is undefined (i.e. you'll get the occasional// segmentation fault/memory exception).////multi_threaded_global- Your program is assumed to be multi threaded. Objects using signals and// slots can be safely created and destroyed from any thread, even when// connections exist. In multi_threaded_global mode, this is achieved by a// single global mutex (actually a critical section on Windows because they// are faster). This option uses less OS resources, but results in more// opportunities for contention, possibly resulting in more context switches// than are strictly necessary.////multi_threaded_local- Behaviour in this mode is essentially the same as multi_threaded_global,// except that each signal, and each object that inherits has_slots, all // have their own mutex/critical section. In practice, this means that// mutex collisions (and hence context switches) only happen if they are// absolutely essential. However, on some platforms, creating a lot of // mutexes can slow down the whole OS, so use this option with care.////USING THE LIBRARY////See the full documentation at http://sigslot.sourceforge.net/////#ifndef SIGSLOT_H__#define SIGSLOT_H__#include <set>#include <list>#if defined(SIGSLOT_PURE_ISO) || (!defined(WIN32) && !defined(__GNUG__) && !defined(SIGSLOT_USE_POSIX_THREADS))#define _SIGSLOT_SINGLE_THREADED#elif defined(WIN32)#define _SIGSLOT_HAS_WIN32_THREADS#include <windows.h>#elif defined(__GNUG__) || defined(SIGSLOT_USE_POSIX_THREADS)#define _SIGSLOT_HAS_POSIX_THREADS#include <pthread.h>#else#define _SIGSLOT_SINGLE_THREADED#endif#ifndef SIGSLOT_DEFAULT_MT_POLICY#ifdef _SIGSLOT_SINGLE_THREADED#define SIGSLOT_DEFAULT_MT_POLICY single_threaded#else#define SIGSLOT_DEFAULT_MT_POLICY multi_threaded_local#endif#endifnamespace sigslot {class single_threaded{public:single_threaded(){;}virtual ~single_threaded(){;}virtual void lock(){;}virtual void unlock(){;}};#ifdef _SIGSLOT_HAS_WIN32_THREADS// The multi threading policies only get compiled in if they are enabled.class multi_threaded_global{public:multi_threaded_global(){static bool isinitialised = false;if(!isinitialised){InitializeCriticalSection(get_critsec());isinitialised = true;}}multi_threaded_global(const multi_threaded_global&){;}virtual ~multi_threaded_global(){;}virtual void lock(){EnterCriticalSection(get_critsec());}virtual void unlock(){LeaveCriticalSection(get_critsec());}private:CRITICAL_SECTION* get_critsec(){static CRITICAL_SECTION g_critsec;return &g_critsec;}};class multi_threaded_local{public:multi_threaded_local(){InitializeCriticalSection(&m_critsec);}multi_threaded_local(const multi_threaded_local&){InitializeCriticalSection(&m_critsec);}virtual ~multi_threaded_local(){DeleteCriticalSection(&m_critsec);}virtual void lock(){EnterCriticalSection(&m_critsec);}virtual void unlock(){LeaveCriticalSection(&m_critsec);}private:CRITICAL_SECTION m_critsec;};#endif // _SIGSLOT_HAS_WIN32_THREADS#ifdef _SIGSLOT_HAS_POSIX_THREADS// The multi threading policies only get compiled in if they are enabled.class multi_threaded_global{public:multi_threaded_global(){pthread_mutex_init(get_mutex(), NULL);}multi_threaded_global(const multi_threaded_global&){;}virtual ~multi_threaded_global(){;}virtual void lock(){pthread_mutex_lock(get_mutex());}virtual void unlock(){pthread_mutex_unlock(get_mutex());}private:pthread_mutex_t* get_mutex(){static pthread_mutex_t g_mutex;return &g_mutex;}};class multi_threaded_local{public:multi_threaded_local(){pthread_mutex_init(&m_mutex, NULL);}multi_threaded_local(const multi_threaded_local&){pthread_mutex_init(&m_mutex, NULL);}virtual ~multi_threaded_local(){pthread_mutex_destroy(&m_mutex);}virtual void lock(){pthread_mutex_lock(&m_mutex);}virtual void unlock(){pthread_mutex_unlock(&m_mutex);}private:pthread_mutex_t m_mutex;};#endif // _SIGSLOT_HAS_POSIX_THREADStemplate<typename mt_policy>class lock_block{public:mt_policy *m_mutex;lock_block(mt_policy *mtx): m_mutex(mtx){m_mutex->lock();}~lock_block(){m_mutex->unlock();}};template<typename mt_policy>class has_slots; template<typename mt_policy, typename ... Args> class _connection_base_normal { public: virtual has_slots<mt_policy>* getdest() const = 0; virtual void emit(Args...) = 0; virtual _connection_base_normal<mt_policy, Args...>* clone() = 0; virtual _connection_base_normal<mt_policy, Args...>* duplicate(has_slots<mt_policy>* pnewdest) = 0; };template<typename mt_policy>class _signal_base : public mt_policy{public:virtual void slot_disconnect(has_slots<mt_policy>* pslot) = 0;virtual void slot_duplicate(const has_slots<mt_policy>* poldslot, has_slots<mt_policy>* pnewslot) = 0;};template<typename mt_policy = SIGSLOT_DEFAULT_MT_POLICY>class has_slots : public mt_policy {private:typedef std::set<_signal_base<mt_policy>*> sender_set; typedef typename sender_set::const_iterator set_const_iterator;public:has_slots(){;}has_slots(const has_slots& hs): mt_policy(hs){lock_block<mt_policy> lock(this); set_const_iterator it = hs.m_senders.begin(); set_const_iterator itEnd = hs.m_senders.end();while(it != itEnd){(*it)->slot_duplicate(&hs, this);m_senders.insert(*it);++it;}} void signal_connect(_signal_base<mt_policy>* sender){lock_block<mt_policy> lock(this);m_senders.insert(sender);}void signal_disconnect(_signal_base<mt_policy>* sender){lock_block<mt_policy> lock(this);m_senders.erase(sender);}virtual ~has_slots(){disconnect_all();}void disconnect_all(){lock_block<mt_policy> lock(this); auto it = m_senders.begin(); auto itEnd = m_senders.end();while(it != itEnd){(*it)->slot_disconnect(this);++it;}m_senders.erase(m_senders.begin(), m_senders.end());}private:sender_set m_senders;};template<typename mt_policy, typename ... Args>class _signal_base_normal : public _signal_base<mt_policy>{public: typedef std::list<_connection_base_normal<mt_policy, Args...> *> connections_list;_signal_base_normal(){;} _signal_base_normal(const _signal_base_normal<mt_policy, Args...>& s): _signal_base<mt_policy>(s){lock_block<mt_policy> lock(this);connections_list::const_iterator it = s.m_connected_slots.begin();connections_list::const_iterator itEnd = s.m_connected_slots.end();while(it != itEnd){(*it)->getdest()->signal_connect(this);m_connected_slots.push_back((*it)->clone());++it;}}void slot_duplicate(const has_slots<mt_policy>* oldtarget, has_slots<mt_policy>* newtarget){lock_block<mt_policy> lock(this);connections_list::iterator it = m_connected_slots.begin();connections_list::iterator itEnd = m_connected_slots.end();while(it != itEnd){if((*it)->getdest() == oldtarget){m_connected_slots.push_back((*it)->duplicate(newtarget));}++it;}}~_signal_base_normal(){disconnect_all();}void disconnect_all(){lock_block<mt_policy> lock(this);connections_list::const_iterator it = m_connected_slots.begin();connections_list::const_iterator itEnd = m_connected_slots.end();while(it != itEnd){(*it)->getdest()->signal_disconnect(this);delete *it;++it;}m_connected_slots.erase(m_connected_slots.begin(), m_connected_slots.end());}void disconnect(has_slots<mt_policy>* pclass){lock_block<mt_policy> lock(this);connections_list::iterator it = m_connected_slots.begin();connections_list::iterator itEnd = m_connected_slots.end();while(it != itEnd){if((*it)->getdest() == pclass){delete *it;m_connected_slots.erase(it);pclass->signal_disconnect(this);return;}++it;}}void slot_disconnect(has_slots<mt_policy>* pslot){lock_block<mt_policy> lock(this);connections_list::iterator it = m_connected_slots.begin();connections_list::iterator itEnd = m_connected_slots.end();while(it != itEnd){connections_list::iterator itNext = it;++itNext;if((*it)->getdest() == pslot){m_connected_slots.erase(it);//delete *it;}it = itNext;}}protected:connections_list m_connected_slots; };template<typename dest_type, class mt_policy, typename ... Args>class _connection_normal : public _connection_base_normal<mt_policy, Args...>{public:_connection_normal(){pobject = NULL;pmemfun = NULL;} _connection_normal(dest_type* pobject, void (dest_type::*pmemfun)(Args...)){m_pobject = pobject;m_pmemfun = pmemfun;} virtual _connection_base_normal<mt_policy, Args...>* clone(){ return new _connection_normal<dest_type, mt_policy, Args...>(*this);} virtual _connection_base_normal<mt_policy, Args...>* duplicate(has_slots<mt_policy>* pnewdest){ return new _connection_normal<dest_type, mt_policy, Args...>((dest_type *)pnewdest, m_pmemfun);} virtual void emit(Args... args){ (m_pobject->*m_pmemfun)(args...);}virtual has_slots<mt_policy>* getdest() const{return m_pobject;}private:dest_type* m_pobject;void (dest_type::* m_pmemfun)(Args...);};template<typename mt_policy, typename ... Args>class signal_normal : public _signal_base_normal<mt_policy, Args...>{public:signal_normal(){;} signal_normal(const signal_normal<mt_policy, Args...>& s) : _signal_base_normal<mt_policy, Args...>(s){;}template<typename desttype>void connect(desttype* pclass, void (desttype::*pmemfun)(Args...)){lock_block<mt_policy> lock(this);_connection_normal<desttype, mt_policy, Args...>* conn = new _connection_normal<desttype, mt_policy, Args...>(pclass, pmemfun);m_connected_slots.push_back(conn);pclass->signal_connect(this);}void emit(Args...args){lock_block<mt_policy> lock(this);auto itNext = m_connected_slots.begin(); auto it = itNext;auto itEnd = m_connected_slots.end();while(it != itEnd){itNext = it;++itNext; (*it)->emit(args...);it = itNext;}}void operator()(Args ...){lock_block<mt_policy> lock(this);connections_list::const_iterator itNext, it = m_connected_slots.begin();connections_list::const_iterator itEnd = m_connected_slots.end();while(it != itEnd){itNext = it;++itNext;(*it)->emit(Args...);it = itNext;}}}; template<typename ... Args> class signal_defalut : public signal_normal <SIGSLOT_DEFAULT_MT_POLICY, Args... > { };}; // namespace sigslot#endif // SIGSLOT_H__
0 0
- sigslot的动态模板版本
- 有用的库-sigslot
- sigslot库的使用
- libjingle sigslot的使用
- sigslot.h的使用
- Sigslot
- sigslot
- sigslot库的使用2
- sigslot库的简单使用
- webrtc中的sigslot的使用
- sigslot.h个人的想法
- sigslot库的简单使用
- sigSlot 简单的信号插槽例子
- 关于SIGSLOT的一个简单Demo
- 可编译与不可编译的sigslot
- c++ 关于sigslot库的调用例子
- Juno版本的Eclipse才支持将Maven的webapp项目转换成3.0版本的动态网页模板吗?
- 动态规划的基础模板
- python操作mysql数据库(增删查改)
- javascript获取点击<li>标签里的值
- 关于Android电池管理系统(二)
- UMeng将当前页面转为图片然后分享
- oracle函数简单例子有返回值
- sigslot的动态模板版本
- 设计模式(3)-结构型-组合模式(Composite)
- Stree
- 安全相关一:iPhone锁机清除密码
- Windows访问Ubuntu14.04远程桌面全攻略(修改版)
- Redis学习笔记04--hashes数据类型
- Fragment中嵌套viewPager,viewPagerh中还有多个子Fragment
- iOS友盟推送发送失败
- Premake可生成vcxproj.filters