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
'개발관련 > C&C++' 카테고리의 다른 글
StringFormat (0) | 2018.03.20 |
---|---|
라이브러리 빌드 전/후 이벤트 명령어 (0) | 2018.03.16 |
Convert Json To Xml (0) | 2018.01.17 |
Xmllite SAX(Simple Api for Xml) TreeNode 구현 및 LIB (XMLParser) (0) | 2018.01.11 |
IOCP ThreadPool 구현 Lib 및 사용 방법 (0) | 2018.01.11 |