#include <chrono>
#include <thread>
#include <future>
#include <iostream>
#include <cstdint>
#include <functional>
#include <list>
#include <unordered_set>
#include <bits/stl_algo.h>
template <typename T>
using ActionConnectorHandler = std::function<void(const T&)>;
template <typename T>
class ActionConnector
{
public:
ActionConnector(ActionConnectorHandler<T> action) : _action(action)
{
}
void operator+=(const T& handler)
{
_action(handler);
}
private:
ActionConnectorHandler<T> _action {
nullptr };
};
template <typename ArgType>
class EventNotifier
{
public:
using EventNotifierHandler = std::function<void(const ArgType&)>;
using MethodList = std::list<EventNotifierHandler>;
using ValueList = std::list<ArgType>;
EventNotifier() {
}
virtual ~EventNotifier()
{
clear();
}
uint8_t invokeMethodList(const ArgType& arg, const MethodList& methods)
{
uint8_t number = 0;
for(const auto& handler : methods){
if(handler != nullptr)
{
handler(arg);
++number;
}
}
return number;
}
void invoke(const ArgType& arg)
{
uint8_t number = invokeMethodList(arg, _handlers);
std::cout<<"有"<<(int)number<<"个通用执行动作被调用"<<std::endl;
invokeMethodList(arg, _watchingHandlers);
std::cout<<"有"<<count<<"个特定监控动作被调用"<<std::endl;
count = 0;
}
public:
void watch(const ArgType& value, const EventNotifierHandler& handler)
{
if (handler == nullptr)
{
return;
}
_watchingHandlers.push_back([=](const ArgType& v)
{
if (value == v)
{
handler(v);
++count;
}
});
}
void watch(const ValueList& values, const EventNotifierHandler& handler)
{
if (handler == nullptr || values.empty())
{
return;
}
_watchingHandlers.push_back([=](const ArgType& value) {
if(values.end() != std::find(values.begin(), values.end(), value)) {
handler(value);
++count;
}
});
}
void clearWatchers()
{
_watchingHandlers.clear();
}
protected:
MethodList _watchingHandlers;
int count = 0;
public:
void operator+=(const EventNotifierHandler& obj)
{
append(obj);
}
void append(const EventNotifierHandler& handler)
{
_handlers.emplace_back(std::move(handler));
}
template <typename T>
void appendEx(std::function<void(const T&)> handler)
{
auto event_handler = [handler](const ArgType& value) {
handler(static_cast<T>(value));
};
_handlers.emplace_back(std::move(event_handler));
}
void clear()
{
_handlers.clear();
}
protected:
MethodList _handlers;
};
template <typename T>
class FieldType
{
public:
FieldType() : FieldType({
}, true) {
}
FieldType(const T& value) : FieldType(value, true) {
}
FieldType(const T& value, const bool& isInitial) {
_value = value;
_isInitialValue = isInitial;
}
virtual void init() const
{
_isInitialValue = true;
}
void update(const T& value) const
{
_value = value;
_isInitialValue = false;
}
bool isInitial() const
{
return _isInitialValue;
}
const T& value() const
{
return _value;
}
protected:
mutable bool _isInitialValue {
true };
mutable T _value {
};
};
template <typename T>
class CachedFieldType : public FieldType<T>
{
public:
using FieldType<T>::FieldType;
void update(const T& value) const
{
_lastValue = FieldType<T>::value();
FieldType<T>::update(value);
}
const T& lastValue() const
{
return _lastValue;
}
protected:
mutable T _lastValue {
};
};
template <typename T>
class CachedStateField
{
public:
CachedStateField() : CachedStateField(T()) {
}
CachedStateField(const T& value) : _field(value) {
}
virtual ~CachedStateField()
{
}
void pushUpdate(const T& value)
{
_changingValues.emplace_back(value);
}
const std::list<T>& pendingChanges()
{
return _changingValues;
}
void update(const T& value)
{
_field.update(value);
_notifier.invoke(value);
invokeWatcher(value);
}
const T& value()
{
return _field.value();
}
const T& lastValue()
{
return _field.lastValue();
}
bool isInitial()
{
return _field.isInitial();
}
public:
using WatchHandler = std::function<void(const T&)>;
ActionConnector<WatchHandler> onChanged {
[this](WatchHandler handler)
{
_notifier += handler;
} };
void watch(const T& value, const WatchHandler& handler)
{
_notifier.watch(value, handler);
}
void watch(const std::list<T>& values, const WatchHandler& handler)
{
_notifier.watch(values, handler);
}
void watch(const T& lastValue, const T& value, const WatchHandler& handler)
{
if (handler == nullptr)
{
return;
}
_watchHandlers.emplace_back([this, lastValue, value, handler](T v)
{
if (_field.lastValue() == lastValue && _field.value() == value)
{
handler(_field.value());
}
});
}
protected:
void invokeWatcher(const T& value)
{
for (const auto& handler : _watchHandlers)
{
if (handler != nullptr)
{
handler(value);
}
}
}
protected:
std::list<T> _changingValues;
EventNotifier<T> _notifier;
CachedFieldType<T> _field;
std::list<WatchHandler> _watchHandlers;
};
int main()
{
CachedStateField<std::string> field("initial value");//被监控的对象
auto GeneralActions1 = [](const std::string& value)
{
std::cout << "通用执行动作1,只要值发生变化,该动作就会触发: " << value << std::endl;
};
auto GeneralActions2 = [](const std::string& value)
{
std::cout << "通用执行动作2,只要值发生变化,该动作就会触发: " << value << std::endl;
};
field.onChanged += GeneralActions1;
field.onChanged += GeneralActions2;//将通用触发动作跟值进行绑定
field.update("new value");// 更新字段的值
//理论上,此时2个通用执行动作会触发
std::cout<<"________________________________________________________________"<<std::endl;
// 定义特定的触发动作,只有更新为某个值时才触发
auto watcher1 = [](const std::string& value)
{
std::cout << "观察者1号:监控特定的值: " << value << "监测成功!"<<std::endl;
};
// 定义特定的触发动作,只有更新为某一组特定的值时才触发
auto watcher11 = [](const std::string& value)
{
std::cout << "高级观察者:监控一组特定的值: " << value << "监测成功!"<<std::endl;
};
field.watch("new value", watcher1);//绑定
field.update("我变化了");//不是特定的值“new value",不会触发动作
std::cout<<"________________________________________________________________"<<std::endl;
field.update("new value");//监控到特定的值:new value,触发动作watcher1
std::cout<<"________________________________________________________________"<<std::endl;
// 监视一组值
std::list<std::string> values = {
"initial value", "new value" };
field.watch(values, watcher11);//绑定
field.update("initial value");
std::cout<<"________________________________________________________________"<<std::endl;
auto watcher2 = [](const std::string& value)
{
std::cout << "顶级观察者,只有当initial value变化成newvalue时此功能才触发: " << value << std::endl;
};
// 监视指定的上一个值和当前值
field.watch("initial value", "new value", watcher2);//绑定:只有由initial value变成new value时才会触发;
field.update("new value");//触发
return 0;
}
[C++] SOMEIP はフィールド値の変更を監視し、応答アクションを実行します
おすすめ
転載: blog.csdn.net/weixin_43717839/article/details/130327462
おすすめ
ランキング