
특정 상황 때 호출되어야 하는 함수들을 관리해주는 class EventManager를 만들어보았다.
이 클래스는 싱글톤으로 해서 어디서든지 이벤트 함수를 등록할 수 있게 했다.
class EventManager : public TSingleton<EventManager>
{
public:
EventManager() = default;
~EventManager() = default;
void Clear();
public:
Event<IScene*> OnSceneChange;
};
이벤트 매니저 클래스 자체는 간단하다.
Clear 함수는 모든 이벤트 함수들을 없애주는 함수이다.
여기서 Event<IScene*> OnSceneChange 변수에 씬이 변경될 때 호출될 이벤트 함수들이 저장되어있다.
template <class... Args>
class Event
{
public:
Event() = default;
~Event() = default;
void operator()(const Args&... args)
{
std::erase_if(m_callbacks, [&](const auto& f) { return f(args...); });
}
friend void operator+=(Event& event, const std::function<bool(Args...)>& callback)
{
event.m_callbacks.push_back(callback);
}
void Clear()
{
m_callbacks.clear();
}
private:
std::vector<std::function<bool(Args...)>> m_callbacks;
};
Event 클래스는 std::vector로 호출 할 이벤트 함수들을 갖고 있다.
operator+= 연산자 오버로딩을 통해 이벤트 함수를 추가할 수 있게 했다.
탬플릿 인자로 받는 클래스들은 이벤트 함수의 파라미터와 동일하다.
if (auto em{ EventManager::GetInstance() })
em->OnSceneChange += [](IScene* scene)
{
OutputDebugString(TEXT("OnSceneChange callback function is called!\n"));
return false;
};
이벤트 함수로 람다 함수를 추가하려면 이런식으로 하면 된다.
이벤트 함수의 리턴값이 true일 경우 한 번 호출된 후 삭제되고 false일 경우 계속 호출된다.
if (auto em{ EventManager::GetInstance() })
em->OnSceneChange += std::bind_front(&WndManager::OnSceneChange, this);
//em->OnSceneChange += std::bind(&WndManager::OnSceneChange, this, std::placeholders::_1);
이벤트 함수로 클래스 멤버 함수를 추가하려면 이런식으로 하면 된다.
std::bind_front는 C++20이 필요하다.
이걸 쓰면 일일히 std::placeholders를 파라미터 개수만큼 쓸 필요가 없다.
이 클래스를 잘 써봐야겠다!
'programming > project' 카테고리의 다른 글
| [013] Direct2D 렌더링 코드 구조 변경 (0) | 2023.11.05 |
|---|---|
| [012] 로그인서버1 (0) | 2023.09.26 |
| [010] 플레이어 컨트롤2 (0) | 2023.07.29 |
| [009] 플레이어 컨트롤 (0) | 2023.06.06 |
| [008] 에디트 컨트롤 (0) | 2023.03.25 |