c++ delegate实现

废话不多说,上代码

#pragma once

#include <mutex>
#include <thread>

template<typename T>
class Lockable
{
private:
    T _data;
    mutable std::recursive_mutex _mutex;

    friend class Ptr;
    friend class ConstPtr;

public:
    struct Ptr
    {
        Ptr(Lockable* lockable)
        : _lockable(lockable)
        , _lock(_lockable->_mutex)
        {
        }
        T& operator*()
        {
            if(_lockable)
            {
                return _lockable->_data;
            }
            throw("Attempt to dereference a detached Lockable::Ptr");
        }
        T* operator->()
        {
            if(_lockable)
            {
                return &_lockable->_data;
            }
            return nullptr;
        }
        operator bool()
        {
            return _lockable != nullptr;
        }
    private:
        Lockable* _lockable;
        std::unique_lock<std::recursive_mutex> _lock;
    };

    struct ConstPtr
    {
        ConstPtr(const Lockable* lockable)
        : _lockable(lockable)
        , _lock(_lockable->_mutex)
        {
        }
        const T& operator*()
        {
            if(_lockable)
            {
                return _lockable->_data;
            }
            throw("Attempt to dereference a detached Lockable::ConstPtr");
        }
        const T* operator->()
        {
            if(_lockable)
            {
                return &_lockable->_data;
            }
            return nullptr;
        }
        operator bool()
        {
            return _lockable != nullptr;
        }
    private:
        const Lockable* _lockable;
        std::unique_lock<std::recursive_mutex> _lock;
    };

public:
    template<typename... Args>
    Lockable(Args... args)
    : _data(args...)
    {
    }

    Ptr lock()
    {
        return std::move(Ptr(this));
    }

    ConstPtr readLock() const
    {
        return std::move(ConstPtr(this));
    }
};
#pragma once

#include <functional>
#include <vector>

#include "Lockable.hpp"

template<typename Signature>
class Delegate;

template<typename R, typename...Args>
class Delegate<R(Args...)>
{
public:
    using Callback = std::function<R(Args...)>;

    struct Entry
    {
        Entry(const Callback& callback)
        : _callback([callback](const std::shared_ptr<void>&, Args... args){ callback(args...); })
        {}

        Entry(const std::shared_ptr<void>& ptr, const Callback& callback)
        : _wptr(ptr)
        , _callback([callback](const std::shared_ptr<void>&, Args... args){ callback(args...); })
        {}

        Entry(const std::shared_ptr<void>& ptr, const std::function<void(const std::shared_ptr<void>&, Args...)>& callback)
        : _wptr(ptr)
        , _callback(callback)
        {}

        std::weak_ptr<void> _wptr;
        std::function<void(const std::shared_ptr<void>&, Args...)> _callback;
    };

    template<typename T>
    struct CallbackBuilder
    {
        CallbackBuilder(Delegate* delegate, std::shared_ptr<T> instance)
        : _delegate(delegate)
        , _instancePtr(instance)
        {
        }

        void operator,(void (T::*mFunc)(Args...))
        {
            _delegate->addEntry(Entry(_instancePtr, [mFunc](const std::shared_ptr<void>& ptr, Args... args){
                if(auto instancePtr = *(std::shared_ptr<T>*)(&ptr))
                {
                    ((*instancePtr).*mFunc)(args...);
                }
            }));
        }

        void operator,(const Callback& callback)
        {
            _delegate->addEntry(Entry(_instancePtr, [callback](const std::shared_ptr<void>&, Args... args){
                callback(args...);
            }));
        }

        Delegate* _delegate;
        std::shared_ptr<T> _instancePtr;
    };

public:
    void addEntry(const Entry& entry)
    {
        if(auto entries = _entries.lock())
        {
            entries->emplace_back(entry);
        }
    }

    void operator()(Args... args) const
    {
        for(auto& entry : *(_entries.readLock()))
        {
            entry._callback(entry._wptr.lock(), args...);
        }
    }

    Delegate& operator+=(const Callback& callback)
    {
        addEntry(Entry(callback));
        return *this;
    }

    Delegate& operator+=(void(*func)(Args...))
    {
        addEntry(Entry(Callback(func)));
        return *this;
    }

    template<typename T>
    CallbackBuilder<T> operator+=(T* instance)
    {
        return CallbackBuilder<T>(this, instance->shared_from_this());
    }

    template<typename T>
    CallbackBuilder<T> operator+=(const std::shared_ptr<T>& instance)
    {
        return CallbackBuilder<T>(this, instance);
    }

protected:
    mutable Lockable<std::vector<Entry>> _entries;
};

转载于:https://www.cnblogs.com/nackee/p/11413231.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值