webrtc(1) 信号槽sigslot

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/NB_vol_1/article/details/80004362

信号槽sigslot    

 

信号槽的作用

    webrtc中有一个重要基础组件——信号槽,它和qt中的信号槽类似,它以发送信号的方式分离调用者和被调用者,达到耦合的目的。另外,webrtc中的信号槽是线程安全的。

信号槽的用法 

#include "sigslot.h"
#include <string>
using namespace std;
using namespace sigslot;

// 信号发送者
class MessageSender {
public:
	void sendMsg() {
		string id = "000001";
		string name = "jack";
		msg_sig(id, name);
	}
public:
	// 定义一个包含两个参数的信号
	sigslot::signal2<string, string> msg_sig;
};

// 信号接收者,需要继承sigslot::has_slots<>
class MessageReceiver:public sigslot::has_slots<>{
public:
	// 处理信号
	void receiveMsg(string id,string name) {
		fprintf(stderr, "id=%s,name=%s\n", id.c_str(), name.c_str());
	}
};

int main()
{
	MessageSender sender;
	MessageReceiver receiver;

	// 绑定信号和槽
	sender.msg_sig.connect(&receiver, &MessageReceiver::receiveMsg);

	// 发送消息
	for (int i = 0; i < 1024; ++i) {
		sender.sendMsg();
	}
    return 0;
}

信号槽的用法如下:

1、定义信号

sigslot::signal2<string, string> msg_sig;

2、定义槽

class MessageReceiver:public sigslot::has_slots<>{
public:
	// 处理信号
	void receiveMsg(string id,string name) {
		fprintf(stderr, "id=%s,name=%s\n", id.c_str(), name.c_str());
	}
};

3、把信号和槽连接起来

sender.msg_sig.connect(&receiver, &MessageReceiver::receiveMsg);

4、发送信号

sender.sendMsg();

信号槽的组成

信号槽有三个部分:

1、信号

signal0,signal1,signal2...都是信号类,它们的实现基本一样,仅参数的数量不同

template<class arg1_type, class arg2_type, class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
	class signal2 : public _signal_base2<arg1_type, arg2_type, mt_policy>
	{
	public:
		typedef _signal_base2<arg1_type, arg2_type, mt_policy> base;
		typedef typename base::connections_list connections_list;
		using base::m_connected_slots;

		signal2()
		{
			;
		}

		signal2(const signal2<arg1_type, arg2_type, mt_policy>& s)
			: _signal_base2<arg1_type, arg2_type, mt_policy>(s)
		{
			;
		}

		// 把信号和槽连接在一起,实际上是通过_connection2进行连接的
		template<class desttype>
			void connect(desttype* pclass, void (desttype::*pmemfun)(arg1_type,
			arg2_type))
		{
				// 加锁(单线程的时候锁函数是空的)
			lock_block<mt_policy> lock(this);
			// 创建连接器(管道),参数分包是信号 和 槽
			_connection2<desttype, arg1_type, arg2_type, mt_policy>* conn = new
				_connection2<desttype, arg1_type, arg2_type, mt_policy>(pclass, pmemfun);
			m_connected_slots.push_back(conn);
			pclass->signal_connect(this);
		}

			// 发射信号(即触发消息发送,实质就是进行函数调用)
		void emit(arg1_type a1, arg2_type a2)
		{
			lock_block<mt_policy> lock(this);
			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
			typename connections_list::const_iterator itEnd = m_connected_slots.end();

			while(it != itEnd)
			{
				itNext = it;
				++itNext;

				(*it)->emit(a1, a2);

				it = itNext;
			}
		}

		// 和emit一样
		void operator()(arg1_type a1, arg2_type a2)
		{
			lock_block<mt_policy> lock(this);
			typename connections_list::const_iterator itNext, it = m_connected_slots.begin();
			typename connections_list::const_iterator itEnd = m_connected_slots.end();

			while(it != itEnd)
			{
				itNext = it;
				++itNext;

				(*it)->emit(a1, a2);

				it = itNext;
			}
		}
	};

2、连接器(管道)

_connection0,_connection1,_connection2...都是连接器(管道)类,它们的实现都是一样的,仅参数的数量不同

template<class dest_type, class arg1_type, class arg2_type, class mt_policy>
	class _connection2 : public _connection_base2<arg1_type, arg2_type, mt_policy>
	{
	public:
		_connection2()
		{
			m_pobject = NULL;
			m_pmemfun = NULL;
		}

		_connection2(dest_type* pobject, void (dest_type::*pmemfun)(arg1_type,
			arg2_type))
		{
			m_pobject = pobject;
			m_pmemfun = pmemfun;
		}

		virtual ~_connection2()
		{
                }

		virtual _connection_base2<arg1_type, arg2_type, mt_policy>* clone()
		{
			return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>(*this);
		}

		virtual _connection_base2<arg1_type, arg2_type, mt_policy>* duplicate(has_slots_interface* pnewdest)
		{
			return new _connection2<dest_type, arg1_type, arg2_type, mt_policy>((dest_type *)pnewdest, m_pmemfun);
		}

		// 触发消息响应
		virtual void emit(arg1_type a1, arg2_type a2)
		{
			(m_pobject->*m_pmemfun)(a1, a2);
		}

		virtual has_slots_interface* getdest() const
		{
			return m_pobject;
		}

	private:
		dest_type* m_pobject;
		void (dest_type::* m_pmemfun)(arg1_type, arg2_type);
	};

3、槽

/*
	** 槽
	*/
	template<class mt_policy = SIGSLOT_DEFAULT_MT_POLICY>
	class has_slots : public has_slots_interface, public mt_policy
	{
	private:
		typedef std::set<_signal_base_interface*> sender_set; // 多个消息可以发送到一个槽
		typedef sender_set::const_iterator const_iterator;

	public:
		has_slots()
		{
			;
		}

		has_slots(const has_slots& hs)
		{
			lock_block<mt_policy> lock(this);
			const_iterator it = hs.m_senders.begin();
			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_interface* sender)
		{
			lock_block<mt_policy> lock(this);
			m_senders.insert(sender);
		}

		// 断开信号和槽的连接
		void signal_disconnect(_signal_base_interface* 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);
			const_iterator it = m_senders.begin();
			const_iterator 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;
	};

猜你喜欢

转载自blog.csdn.net/NB_vol_1/article/details/80004362