1. 程式人生 > >C++ 自定義事件機制2

C++ 自定義事件機制2


可以使用成員函式指標,用到了類模版!

---------------------------------------------------------------

1、要定義一個事件基類,可以使用它傳遞不懂型別的引數。

myevent.h

#pragma once

#include <iostream>
#include <string>
using namespace std;
class MyEvent
{
public:
	MyEvent(string type);
	~MyEvent();
	string getType();
protected:
private:
	string _type;
};

myevent.cpp
#include "myevent.h"

MyEvent::MyEvent(string type)
{
	_type = type;
	cout << "MyEvent()" << endl;
}

MyEvent::~MyEvent()
{
	cout << "~MyEvent()" << endl;
}

std::string MyEvent::getType()
{
	return _type;
}


2、然後要有一個型別和函式指標的模版類。

eventitem.h

#pragma once

#include "myevent.h"
#include <memory>

template <typename T>
class EventItem
{
	typedef void(T::*ItemFUN)(MyEvent&);
public:
	EventItem()
	{
		cout << "EventItem()" << endl;
	}

	~EventItem()
	{
		cout << "~EventItem()" << endl;
	}

	void (T::*f)(MyEvent&);
	shared_ptr<T> t;
};

3、定義事件收發管理類

eventdispatcher.h

#pragma once

#include <unordered_map>
#include <string>
#include "myevent.h"
#include <iostream>
#include "eventitem.h"
#include <memory>

using namespace std;

template<typename T>
class EventDispatcher
{
	typedef void(T::*EventFun)(MyEvent&);
public:
	static void addEventListener(string type, shared_ptr<T> t, EventFun f);
	static void dispatchEvent(shared_ptr<MyEvent> sp);
	static void removeEventListener(string type);
	static bool hasEventListener(string type);
private:
	static unordered_map<string, shared_ptr<EventItem<T>>> events;
};

template<typename T>
unordered_map<string, shared_ptr<EventItem<T>>> EventDispatcher<T>::events;

template<typename T>
void EventDispatcher<T>::addEventListener(string type, shared_ptr<T> t, EventFun f)
{
	if (!hasEventListener(type))
	{
		shared_ptr<EventItem<T>> spItem = make_shared<EventItem<T>>();
		spItem->t = t;
		spItem->f = f;
		events[type] = spItem;
	}
	else{
		cout << "事件 " << type << " 已經定義" << endl;
	}
}

template<typename T>
void EventDispatcher<T>::dispatchEvent(shared_ptr<MyEvent> sp)
{
	string& temp = sp->getType();
	if (hasEventListener(temp))
	{
		shared_ptr<EventItem<T>> spItem = events[temp];
		((*spItem).t->*(*spItem).f)(*sp);
		cout << spItem->t->i << endl;
	}
	else{
		cout << "事件 " << temp << " 未定義" << endl;
	}
}

template<typename T>
void EventDispatcher<T>::removeEventListener(string type)
{
	if (hasEventListener(type))
	{
		events.erase(type);
	}
	else{
		cout << "事件 " << type << " 未定義" << endl;
	}
}

template<typename T>
bool EventDispatcher<T>::hasEventListener(string type)
{
	if (events[type] != nullptr)
	{
		return true;
	}
	return false;
}

至此就可以使用了簡單吧~

===========================================================================================

使用案例:

main.cpp

#include <iostream>
#include "eventdispatcher.h"
#include <memory>

class Test
{
public:
	int i;

	Test()
	{
		cout << "Test()" << endl;
	}

	~Test()
	{
		cout << "~Test()" << endl;
	}

	void test(MyEvent& e)
	{
		cout << "what the hell!!!" << endl;
		i++;
	}
protected:
private:
};

void fun()
{
	shared_ptr<Test> pt = make_shared<Test>();
	pt->i = 10;
	EventDispatcher<Test>::addEventListener("hello", pt, &Test::test);
	EventDispatcher<Test>::addEventListener("jj", pt, &Test::test);
}
void del()
{
	EventDispatcher<Test>::removeEventListener("hello");
}
int main()
{
	fun();
	del();
	system("pause");
	return 0;
}