简单的一个信号槽的连接

一个很简陋的信号和槽的连接

#include<iostream>
#include<vector>
#include<string>
#include<Windows.h>
using std::vector;
using std::string;

//调试的时候用来看name,实际上没有用
class UObject
{
public:
	UObject(){};
	//template<class sender,class sig,class recver,class slot>
	//void setsobj(sig signal,UObject* r,slot reactslot){};
	string name;
	

};

template<class sender,class sig,class recver,class slot>
class connectstruct
{
	public:
		connectstruct(sender s,sig signal,recver r,slot reactslot)
		{
			m_s = s;
			m_sig = signal;
			m_r = r;
			m_slot = reactslot;
		}
		sender m_s;
		sig m_sig;
		recver m_r;
		slot m_slot;
};
//记录信号信息的类
template<class sig>
class ssinfor
{
public:
	ssinfor(sig signal)
	{
		m_sig = signal;
		m_count += 1;
		m_c2 = m_count;
	}

	static int m_s;      //发射次数
	static sig m_sig;
	static int m_count;  //连接量
	static int m_c2;
};

template<class sig>
int ssinfor<sig>::m_s = 0;
template<class sig>
sig ssinfor<sig>::m_sig = NULL;
template<class sig>
int ssinfor<sig>::m_count = 0;
template<class sig>
int ssinfor<sig>::m_c2 = 0;


static int i = 90;
template<class sender,class sig,class recver,class slot>
class sigfunc
{
	public:
		typedef vector<connectstruct<sender,sig,recver,slot> *> contype;
		typedef vector<ssinfor<sig>* > calltype;

		sigfunc(connectstruct<sender,sig,recver,slot>* connode)
		{
			funvec.push_back(connode);
			ssinfor<sig> *s = new ssinfor<sig>(connode->m_sig);
			callvec.push_back(s);
			++i;
			//std::cout<<((UObject*)connode->m_r)->name<<std::endl;
			::SetTimer(NULL,i,1000,&sigfunc<sender,sig,recver,slot>::_timerproc);
			//::Sleep(1000);
		}
		
		static contype funvec; 
		static calltype callvec;
		static void CALLBACK _timerproc(
			HWND hwnd, 
			UINT uMsg, 
			UINT idEvent, 
			DWORD dwTime 
			);

};

template<class sender,class sig,class recver,class slot>
vector<connectstruct<sender,sig,recver,slot> *> sigfunc<sender,sig,recver,slot>::funvec;

template<class sender,class sig,class recver,class slot>
vector<ssinfor<sig>* > sigfunc<sender,sig,recver,slot>::callvec;

template<class sender,class sig,class recver,class slot>
void CALLBACK sigfunc<sender,sig,recver,slot>::_timerproc( HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime )
{
	
	//std::cout << L"Timer id :" << idEvent << std::endl;
	if (ssinfor<sig>::m_s == 0)
	{
		ssinfor<sig>::m_c2 = 0;
	}
	else
	{
		//已修正错误
		for (vector<connectstruct<sender,sig,recver,slot> *>::iterator i = funvec.begin(); i!= funvec.end(); ++i)
		{
			//std::cout<<((UObject*)(*i)->m_r)->name<<std::endl;
			if(ssinfor<sig>::m_count != 0)
			{
				if ((*i)->m_sig == ssinfor<sig>::m_sig)
				{
					slot pfn = (*i)->m_slot;
					((*((*i)->m_r)).*pfn)();
					ssinfor<sig>::m_count -= 1;
					if (ssinfor<sig>::m_count == 0)
					{
						ssinfor<sig>::m_s -= 1;
						ssinfor<sig>::m_count = ssinfor<sig>::m_c2;
					}
				}

			}
			
		}
		//ssinfor<sig>::m_s -= 1;

	}
	
}

template<class sender,class sig,class recver,class slot>
void addsignode(connectstruct<sender,sig,recver,slot>* connode)
{
	new sigfunc<sender,sig,recver,slot>(connode);
}

template<class sender,class sig,class recver,class slot>
void connect(sender s,sig signal,recver r,slot reactslot)
{
	
	connectstruct<sender,sig,recver,slot> *connode = new connectstruct<sender,sig,recver,slot>(s,signal,r,reactslot);
	addsignode<sender,sig,recver,slot>(connode);

}

template<class sig>
void callslot(sig)
{
	ssinfor<sig>::m_s += 1;

}

class obj
{
public:
	obj(){};

	void sig1(){
		std::cout<<"sig1 emited"<<std::endl;
		callslot<void (obj::*)()>(&obj::sig1);//信号需要手工调用一次callslot函数

	}

};

class listener  : public UObject
{
public:
	listener(){name = "LIS";}
	void slot1(){
		std::cout<<"listener worked"<<std::endl;
		
	}
	//string name;
};

class viewer: public UObject
{
public:
	viewer(){name = "view";}
	void show()
	{
		std::cout<<"view show worked"<<std::endl;
	}
	//string name;
};

class watcher: public UObject
{
public:
	watcher(){name = "watch";}
	void watch()
	{
		std::cout<<"watch worked!!"<<std::endl;
	}
//string name;
};

int main()
{
	obj *obj1 = new obj;
	listener *lsner1 = new listener;
	connect(obj1,&obj::sig1,lsner1,&listener::slot1);
	//obj1->sig1();
	

	viewer *viewer1 = new viewer;
	connect(obj1,&obj::sig1,viewer1,&viewer::show);
	//obj1->sig1();
	

	watcher *watcher1 = new watcher;
	connect(obj1,&obj::sig1,watcher1,&watcher::watch);
	
	obj1->sig1();
	obj1->sig1();
	obj1->sig1();
	


	MSG msg;
	while (GetMessage(&msg,NULL,NULL,NULL))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	std::cin.get();
	return 0;
}

运行结果


timer设置时间很短的时候槽被触发的顺序会不确定,原因还不清楚,可能是windows里面有对于timer的优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值