Subsystem
랜더링할때 사용하는 Graphics클래스하고 씬을 컨트롤 하는 SceneManager 클래스는 다른 곳에서 사용되는데 싱글톤보단 다른 방법이 좋아서 서브 시스템을 만듦.
ISubsystem.h
class ISubsystem
{
public:
ISubsystem(class Context* context) : context(context) {}
virtual ~ISubsystem() = default;
virtual bool Initialize() = 0;
virtual void Update() = 0;
virtual void Render() {}
const class Context* const GetContext() const { return context; }
protected:
class Context* context = nullptr;
};
추상 클래스이기 때문에 이렇게 cpp파일 없이 선언만 함.
이제 Graphics와 SceneManager를 상속하고, 이 서브시스템들을 컨트롤할 Context클래스 제작
Context.h
#pragma once
#include "Subsystem/ISubsystem.h"
class Context final
{
public:
Context() = default;
~Context();
const bool InitializeSubsystems()
{
bool result = true;
for (const auto& subsystem : subsystems)
{
if (!subsystem->Initialize())
{
result = false;
}
}
return result;
}
template <typename T>
T* const RegisterSubsystem();
template <typename T>
T* const GetSubsystem();
void UpdateSubsystems();
void RenderSubsystems();
private:
std::vector<ISubsystem*> subsystems;
};
template<typename T>
inline T* const Context::RegisterSubsystem()
{
static_assert(std::is_base_of<ISubsystem, T>::value, "Provided type does not implement ISubsystem");
return static_cast<T*>(subsystems.emplace_back(new T(this)));
}
template<typename T>
inline T* const Context::GetSubsystem()
{
static_assert(std::is_base_of<ISubsystem, T>::value, "Provided type does not implement ISubsystem");
// RTTI : Run Time Type Information 사용 하지만 느림
for (const auto& subsystem : subsystems)
{
if (typeid(T) == typeid(*subsystem))
{
return static_cast<T*>(subsystem);
}
}
return nullptr;
}
Context.h
#include "stdafx.h"
#include "Context.h"
Context::~Context()
{
for (auto iter = subsystems.rbegin(); iter != subsystems.rend(); iter++)
{
SAFE_DELETE(*iter);
}
}
void Context::UpdateSubsystems()
{
for (const auto& subsystem : subsystems)
{
subsystem->Update();
}
}
void Context::RenderSubsystems()
{
for (const auto& subsystem : subsystems)
{
subsystem->Render();
}
}
이번에는 Component와는 달리 서브 시스템 하나하나 비교를 하면서 체크함,
왜? 이방식? 서브시스템이 많이 없기 때문에 하나하나 비교하는 것이 퍼포먼스에 큰 영향을 안줄것으로 생각되기 때문
이렇게 만들고,
이 서브시스템들을 한번에 관리해줄 시스템을 만듦
Engine.h
#pragma once
class Engine final
{
public:
Engine();
~Engine();
void Update();
void Render();
private:
class Context* context = nullptr;
};
Engine.cpp
#include "stdafx.h"
#include "Engine.h"
Engine::Engine()
{
context = new Context();
context->RegisterSubsystem<Graphics>();
context->RegisterSubsystem<SceneManager>();
context->InitializeSubsystems();
}
Engine::~Engine()
{
SAFE_DELETE(context);
}
void Engine::Update()
{
context->UpdateSubsystems();
}
void Engine::Render()
{
context->RenderSubsystems();
}
이제 Program.cpp에서 이 엔진을 돌려주면 끝!