[C++] SOMEIP はフィールド値の変更を監視し、応答アクションを実行します

#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;
}

おすすめ

転載: blog.csdn.net/weixin_43717839/article/details/130327462