1
0
mirror of https://github.com/jaredtao/TaoQuick.git synced 2025-01-31 21:22:58 +08:00
2020-10-29 15:26:24 +08:00

99 lines
2.7 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <algorithm>
#include <map>
#include <vector>
namespace TaoCommon {
//观察者模式Subject-Observer。
// Subject 事件或消息的主体。模板参数为观察者类型
template<typename ObserverType>
class Subject
{
public:
virtual ~Subject() { m_obsList.clear(); }
//订阅
void subscibe(ObserverType *obs)
{
auto itor = std::find(m_obsList.begin(), m_obsList.end(), obs);
if (m_obsList.end() == itor) {
m_obsList.push_back(obs);
}
}
//取消订阅
void unSubscibe(ObserverType *obs)
{
m_obsList.erase(std::remove(m_obsList.begin(), m_obsList.end(), obs));
}
//发布。这里的模板参数为函数类型。
template<typename FuncType>
void publish(FuncType func)
{
for (auto obs : m_obsList) {
//调用回调函数将obs作为第一个参数传递
func(obs);
}
}
//发布。支持过滤观察者。通常用在 观察者触发消息发布时,过滤观察者自己。
template<typename FuncType>
void publish(FuncType func, ObserverType *exceptObs)
{
for (auto obs : m_obsList) {
//调用回调函数将obs作为第一个参数传递
if (obs != exceptObs) {
func(obs);
}
}
}
private:
std::vector<ObserverType *> m_obsList;
};
//优先级观察者模式Subject-Observer。
template<typename ObserverType>
class LevelSubject
{
public:
virtual ~LevelSubject() { m_obsMap.clear(); }
//订阅
void subscibe(ObserverType *obs, uint32_t level)
{
auto &vec = m_obsMap[level];
auto itor = std::find(vec.begin(), vec.end(), obs);
if (vec.end() == itor) {
vec.push_back(obs);
}
}
//取消订阅
void unSubscibe(ObserverType *obs)
{
for (auto &obsPair : m_obsMap) {
obsPair.second.erase(std::remove(obsPair.second.begin(), obsPair.second.end(), obs));
}
}
//发布。这里的模板参数为函数类型。
template<typename FuncType>
void publish(FuncType func)
{
for (const auto &obsPair : m_obsMap) {
for (const auto &obs : obsPair.second) {
func(obs);
}
}
}
template<typename FuncType>
void publish(FuncType func, ObserverType *exceptObs)
{
for (const auto &obsPair : m_obsMap) {
for (const auto &obs : obsPair.second) {
if (obs != exceptObs) {
func(obs);
}
}
}
}
private:
std::map<uint32_t, std::vector<ObserverType *>> m_obsMap;
};
} // namespace TaoCommon