// 用于表明一个类是不允许被拷贝的
#define CANNOT_COPY(Classname) \
private: \
Classname(const Classname&);
// 用于表明一个类是不允许被赋值的
#define CANNOT_ASSIGN(Classname) \
private: \
Classname& operator=(const Classname&);
// 用于表明一个类是不允许被拷贝或赋值的
#define CANNOT_COPY_OR_ASSIGN(Classname) \
private: \
Classname(const Classname&); \
Classname& operator=(const Classname&);
//class NonCopyable
//{
//protected:
// NonCopyable() = default;
// ~NonCopyable() = default;
// NonCopyable(const NonCopyable&) = delete; //禁用复制构造函数
// NonCopyable& operator=(const NonCopyable&) = delete;//禁用赋值构造函数
//};
#pragma once
#include "NonCopyable.h"
#include <map>
template<typename Func>
class Events //: public NonCopyable
{
CANNOT_COPY_OR_ASSIGN(Events)
public:
Events() :m_observerId(0)
{
}
~Events() = default;
//增加+=和-=运算符重载,使用法和C#的event用法接近
int operator +=(Func&& f)
{
return Connect(std::forward<Func>(f));
}
int operator+=(Func& f)
{
return Connect(f);
}
template<typename... Args>
void operator()(Args&&... args)
{
Notify(std::forward<Args>(args)...);
}
Events& operator -=(int key)
{
Disconnect(key);
return *this;
}
void Clear()
{
m_connections.clear();
}
private:
//注册观察者,支持右值引用
int Connect(Func&& f)
{
//return Assgin(f);
return Assgin(std::forward<Func>(f));
}
//注册观察者
int Connect(const Func& f)
{
return Assgin(f);
}
//移除观察者
void Disconnect(int key)
{
m_connections.erase(key);
}
//通知所有的观察者
template<typename... Args>
void Notify(Args&&... args)
{
for (auto& it : m_connections)
{
it.second(std::forward<Args>(args)...);
}
}
//保存观察者并分配观察者的编号
template<typename F>
int Assgin(F&& f)
{
int k = m_observerId++;
m_connections.emplace(k, std::forward<F>(f));
return k;
}
private:
int m_observerId; //观察者对应的编号
std::map<int, Func> m_connections; //观察者列表
};
//测试===================================================
#include <iostream>
#include <functional>
#include "Events.h"
using namespace std;
struct StA
{
int a, b;
void Print(int a, int b)
{
cout <<"StA:"<< "a:" << a << ",b:" << b << endl;
}
};
void Print(int a, int b)
{
cout << "a:" << a << ",b:" << b << endl;
}
void Test1()
{
//Events<std::function<void(int, int)>> event1;
////1.以函数方式注册观察者
//auto key = event1.Connect(Print);
//StA sta;
////2.lamda注册
//auto lambdakey = event1.Connect([/*&sta*/](int a, int b) {
// /* sta.a = a;
// sta.b = b;
// cout << ",,," << a << "," << b << endl;*/
// cout << "a + b = " << a + b << endl;
//});
////3.std::function注册
//std::function<void(int, int)> f = std::bind(&StA::Print, &sta, std::placeholders::_1, std::placeholders::_2);
//event1.Connect(f);
//int a = 1, b = 2;
////4.广播所有观察者
//event1.Notify(a, b);
////5.移除观察者
//event1.Disconnect(key);
////cout << "--------------------------" << endl;
//event1.Notify(a, b);
//cout << "=================================================\n";
//Events<std::function<void()>> event2;
//event2.Connect([]() {
// cout << "hello world" << endl;
//});
//event2.Notify();
}
void Test2()
{
using Deletegate = std::function<void(int, int)>;
using Event1 = Events<Deletegate>;
Event1 event1;
auto key1 = event1 += &Print;
StA t;
auto key2 = event1 += [&t](int a, int b) {
cout << "a+b=" << a + b << endl;;
};
auto key3 = event1 += std::bind(&StA::Print, &t, std::placeholders::_1, std::placeholders::_2);
event1(1,2);
}
void main()
{
//测试1
//Test1();
//委托
Test2();
getchar();
}