• Home
  • About
    • 게임 개발자 유정룡 photo

      게임 개발자 유정룡

      포트폴리오

    • Learn More
    • Email
    • Github
    • Bitbucket
  • Projects
    • All Projects
    • All Tags

DirectX11 공부 11일차(Subsystem)

11 Jun 2021

Reading time ~2 minutes

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에서 이 엔진을 돌려주면 끝!



DirectX Share Tweet +1