개발관련/C&C++

C#처럼 이벤트 처리

Diademata 2018. 2. 27. 00:34
반응형

CEF 재작업중.. CEF 콜백에 대한 처리를 Event Bind 형식이 더 편할 것 같은 느낌이라


C# Event처럼 구현함.


template이라 Cpp 파일은 없음. 내부적으로 Delegate리스트는 unique_ptr 을 사용함.



사용법

이벤트 객체

class test

{

public:

Util::Event<bool*> LoadingState;

}


이벤트 구독

//void* sender 타입 고정

//bool* e 인 경우 Generic

void CLauncherDlg::OnLoadingStateChange(void* sender, bool* e)

{

//.....

}

BOOL CLauncherDlg::OnInitDialog()

{

//안에서만 namespace 사용

{

using namespace std::placeholders;

handler->LoadingState += std::bind(&CLauncherDlg::OnLoadingStateChange, this, _1, _2);

}

}


code>>


Ns.h


#pragma once

#ifndef EVENT_H

#define EVENT_H

#define NS_EVENT_BEGIN namespace Util { namespace Event {

#define NS_EVENT_END } }

#define USING_EVENT using namespace Util::Event;

#endif


NS.h


#pragma once

#ifndef COMMON_H

#define COMMON_H

#define NS_COMMON_BEGIN namespace Util { namespace Common {

#define NS_COMMON_END } }

#define USING_COMMON using namespace Util::Common;

#endif


Event.h


#pragma once

#include "../Common/MulticastDelegate.h"

#include <vector>

#include <memory>

#include "NS.h"


NS_EVENT_BEGIN

USING_COMMON

template<typename T>

class Event

{

public:

Event() {}

virtual ~Event()

{

_delegates.clear();

}

private:

std::vector<std::unique_ptr<MulticastDelegate<void, void*, T>>> _delegates;

private:

void operator += (std::unique_ptr<MulticastDelegate<void, void*, T>> func);

void operator -= (std::unique_ptr<MulticastDelegate<void, void*, T>> func);

public:

void operator()(void* sender, T e);

void operator += (std::function<void(void*, T)> func);

void operator -= (std::function<void(void*, T)> func);

void operator += (MulticastDelegate<void, void*, T>* func);

void operator -= (MulticastDelegate<void, void*, T>* func);

};

template<typename T>

inline void Event<T>::operator += (std::unique_ptr<MulticastDelegate<void, void*, T>> func)

{

auto it = _delegates.begin();

while (it != _delegates.end())

{

if (*it == func)

break;

}

if (it == _delegates.end())

{

_delegates.push_back(std::move(func));

}

}

template<typename T>

inline void Event<T>::operator -= (std::unique_ptr<MulticastDelegate<void, void*, T>> func)

{

for (auto it = _delegates.begin(); it != _delegates.end(); ++it)

{

if (*it == func)

{

it = _delegates.erase(it);

}

}

}

template<typename T>

inline void Event<T>::operator += (std::function<void(void*, T)> func)

{

std::unique_ptr<MulticastDelegate<void, void*, T>> ptr(new MulticastDelegate<void, void*, T>(func));

this->operator+=(std::move(ptr));

}

template<typename T>

inline void Event<T>::operator -= (std::function<void(void*, T)> func)

{

std::unique_ptr<MulticastDelegate<void, void*, T>> ptr(new MulticastDelegate<void, void*, T>(func));

this->operator-=(std::move(ptr));

}

template<typename T>

inline void Event<T>::operator += (MulticastDelegate<void, void*, T>* func)

{

std::unique_ptr<MulticastDelegate<void, void*, T>> ptr(func);

this->operator+=(std::move(ptr));

}

template<typename T>

inline void Event<T>::operator -= (MulticastDelegate<void, void*, T>* func)

{

std::unique_ptr<MulticastDelegate<void, void*, T>> ptr(func);

this->operator-=(std::move(ptr));

}

template<typename T>

inline void Event<T>::operator () (void* sender, T e)

{

for (auto it = _delegates.begin(); it != _delegates.end(); ++it)

{

(*it)->operator()(sender, e);

}

}

NS_EVENT_END


Delegate.h


//MulticastDelegate만 생성가능


#pragma once

#include "NS.h"

#include <functional>

#include <vector>

NS_COMMON_BEGIN

template<typename R, typename T1, typename T2, typename T3, typename T4, typename T5>

class MulticastDelegate;


template<typename R, typename ...Types>

class Delegate

{

private:

template<typename R, typename T1, typename T2, typename T3, typename T4, typename T5>

friend class MulticastDelegate;

protected:

std::vector<std::function<R(Types...)>> _methods;

private:

Delegate()

{

_methods.clear();

}

public:

virtual ~Delegate() { _methods.clear(); }

public:

R operator() (Types...);

bool operator != (const Delegate& d) const;

bool operator != (nullptr_t) const;

bool operator == (const Delegate& d) const;

bool operator == (nullptr_t) const;

void operator = (nullptr_t);

void operator = (std::function<R(Types...)>);

Delegate& operator += (std::function<R(Types...)>);

public:

virtual Delegate& Combine(Delegate);

virtual Delegate& operator + (Delegate);

};


template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::Combine(Delegate<R, Types...> del)

{

for (auto m : del._methods)

{

_methods.push_back(m);

}

return *this;

}

template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::operator += (std::function<R(Types...)> method)

{

_methods.push_back(method);

return *this;

}

template<typename R, typename ...Types>

inline Delegate<R, Types...>& Delegate<R, Types...>::operator + (Delegate<R, Types...> del)

{

return Combine(del);

}

template<typename R, typename ...Types>

void Delegate<R, Types...>::operator = (std::function<R(Types...)> method)

{

_methods.clear();

_methods.push_back(method);

}


template<>

inline void Delegate<void>::operator() ()

{

for (auto m : _methods)

{

m();

}

}

template<typename R, typename ...Types>

inline R Delegate<R, Types...>::operator() (Types... params)

{

for (int i = 0; i < _methods.size() - 1; i++)

{

_methods[i](params...);

}

return _methods.back()(params...);

}

template<typename R, typename ...Types>

bool Delegate<R, Types...>::operator != (nullptr_t) const

{

return _methods.size() != 0;

}


template<typename R, typename ...Types>

bool Delegate<R, Types...>::operator != (const Delegate<R, Types...>& del) const

{

return this != &del;

}


template<typename R, typename ...Types>

bool Delegate<R, Types...>::operator == (nullptr_t) const

{

return _methods.size() == 0;

}


template<typename R, typename ...Types>

bool Delegate<R, Types...>::operator == (const Delegate<R, Types...>& del) const

{

return this == &del;

}


template<typename R, typename ...Types>

void Delegate<R, Types...>::operator = (nullptr_t)

{

_methods.clear();

}


NS_COMMON_END


MulticastDelegate.h


#pragma once

#include "NS.h"

#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900)

#include "Delegate.h"

#else

#include "Delegate98.h"

#endif

NS_COMMON_BEGIN

template<typename R, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void>

class MulticastDelegate : public Delegate<R, T1, T2, T3, T4, T5>

{

public:

MulticastDelegate()

{

}

MulticastDelegate(std::function<R(T1, T2, T3, T4, T5)> method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

void operator = (std::function<R(T1, T2, T3, T4, T5)>);

};

template<typename R, typename T1, typename T2, typename T3, typename T4, typename T5>

inline void MulticastDelegate<R, T1, T2, T3, T4, T5>::operator = (std::function<R(T1, T2, T3, T4, T5)> method)

{

Delegate<R, T1, T2, T3, T4, T5>::operator = (method);

}


template<typename R, typename T1, typename T2, typename T3, typename T4>

class MulticastDelegate<R, T1, T2, T3, T4, void> : public Delegate<R, T1, T2, T3, T4>

{

public:

MulticastDelegate()

{

}

MulticastDelegate(std::function<R(T1, T2, T3, T4)> method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

void operator = (std::function<R(T1, T2, T3, T4)>);

};

template<typename R, typename T1, typename T2, typename T3, typename T4>

inline void MulticastDelegate<R, T1, T2, T3, T4>::operator = (std::function<R(T1, T2, T3, T4)> method)

{

Delegate<R, T1, T2, T3, T4>::operator = (method);

}


template<typename R, typename T1, typename T2, typename T3>

class MulticastDelegate<R, T1, T2, T3, void, void> : public Delegate<R, T1, T2, T3>

{

public:

MulticastDelegate()

{

}

MulticastDelegate(std::function<R(T1, T2, T3)> method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

void operator = (std::function<R(T1, T2, T3)>);

};

template<typename R, typename T1, typename T2, typename T3>

inline void MulticastDelegate<R, T1, T2, T3>::operator = (std::function<R(T1, T2, T3)> method)

{

Delegate<R, T1, T2, T3>::operator = (method);

}


template<typename R, typename T1, typename T2>

class MulticastDelegate<R, T1, T2, void, void, void> : public Delegate<R, T1, T2>

{

public:

MulticastDelegate()

{

}

MulticastDelegate(std::function<R(T1, T2)> method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

void operator = (std::function<R(T1, T2)>);

};

template<typename R, typename T1, typename T2>

inline void MulticastDelegate<R, T1, T2>::operator = (std::function<R(T1, T2)> method)

{

Delegate<R, T1, T2>::operator = (method);

}


template<typename R, typename T>

class MulticastDelegate<R, T, void, void, void, void> : public Delegate<R, T>

{

public:

MulticastDelegate()

{

}

MulticastDelegate(std::function<R(T)> method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

void operator = (std::function<R(T)>);

};

template<typename R, typename T>

inline void MulticastDelegate<R, T>::operator = (std::function<R(T)> method)

{

Delegate<R, T>::operator = (method);

}


template<typename R>

class MulticastDelegate<R, void, void, void, void, void> : public Delegate<R>

{

public:

MulticastDelegate()

{

}

MulticastDelegate(std::function<R()> method)

{

this->operator= (method);

}

virtual ~MulticastDelegate() {}

public:

void operator = (std::function<R()> func);

};

template<typename R>

inline void MulticastDelegate<R>::operator = (std::function<R()> method)

{

Delegate<R>::operator = (method);

}

NS_COMMON_END


반응형