씬 매니저와 리소스 최적화 설계


개요

CSceneManager는 게임 진행 중 씬을 선입후출(FILO) 방식스택 구조로 관리하는 싱글톤입니다. 씬 전환은 일관된 상태 전이리소스의 안전한 생성 및 해제를 보장하며, 스마트 포인터 기반 리소스 관리이전 씬과 공유하는 리소스를 재로드 없이 넘겨받아 효율적인 메모리 사용빠른 전환을 지원합니다.

저장소 보기


씬 전환 종류

씬 전환은 ChangeRequest(ETransition, ESceneState) 함수로 요청하며, 호출 시 전환 정보가 mPending에 저장되며, 다음 프레임의 Update(float) 함수가 시작될 때 ChangeApply()를 통해 처리됩니다.

전환 종류역할세부 단계
PushScene()스택 최상단에 새로운 씬 추가1. 새로운 씬 생성
2. 새로운 씬 리소스 로드
3. 스택 최상단에 새로운 씬 추가
4. 새로운 씬 Enter() 호출
PopScene()
스택 최상단 씬 제거1. 스택 최상단 씬 Exit() 호출
2. 스택 최상단 씬 리소스 언로드
3. 스택 최상단 씬 제거
SwapScene()스택 최상단 씬 제거 후, 새로운 씬 추가1. 새로운 씬 생성
2. 새 씬 리소스는 로드하되, 최상단 씬 공통 리소스는 재로드 없이 전달
3. PopScene() 호출
4. 스택 최상단에 새로운 씬 추가
5. 새로운 씬 Enter() 호출
ClearScenes()모든 씬 제거1. 스택에 씬이 없을 때까지PopScene() 호출
ClearThenPushScene()모든 씬 제거 후, 새로운 씬 추가1. 새로운 씬 리소스 로드하되, 모든 씬과의 공통 리소스는 재로드 없이 전달
2. ClearScenes() 호출
3. 스택 최상단에 새로운 씬 추가
4. 새로운 씬 Enter() 호출

씬 전환 리소스 관리 (코드 분석)

⚠️ 참고: 본 코드는 씬 전환 리소스 관리 방식의 설명을 위해 간소화한 코드입니다.

class CTextureManager
{
private:
	std::unordered_map<std::string, std::weak_ptr<CTexture>> mTextures;
	
public:
	std::shared_ptr<CTexture> LoadTexture(...);
}
//---------------------------------------------------------------//
class CFontManager
{
private:
	std::unordered_map<std::string, std::weak_ptr<CFont>> mFonts;
	
public:
	std::shared_ptr<CFont> LoadFont(...);
}
//---------------------------------------------------------------//
class CSoundManager
{
private:
	std::unordered_map<std::string, std::weak_ptr<CSFX>> mSFXs;
	std::unordered_map<std::string, std::weak_ptr<CBGM>> mBGMs;
	
public:
	std::shared_ptr<CSFX> LoadSFX(...);
	std::shared_ptr<CBGM> LoadBGM(...);
}

  • 리소스 매니저는 리소스를 std::weak_ptr로만 보관합니다. 이는 약한 참조만 유지하여 리소스의 소유권을 가지지 않으며, 실제 메모리 해제는 해당 리소스를 shared_ptr로 소유하는 씬에서 모든 참조가 끊어질 때 자동으로 이루어집니다.

class CScene abstract
{
	friend class CSceneManager;
	
protected:
	CScene();
	virtual ~CScene();
	
protected:
	std::vector<std::shared_ptr<class CTexture>> mTextures;
    std::vector<std::shared_ptr<class CFont>> mFonts;
    std::vector<std::shared_ptr<class CSFX>>  mSFXs;
    std::vector<std::shared_ptr<class CBGM>>  mBGMs;
    
protected:
	virtual void LoadResources() = 0;
	
    void UnloadResources()
    {
	    mTextures.clear();
	    mFonts.clear();
	    mSFXs.clear();
	    mBGMs.clear();
    }
}

  • CScene 추상 클래스는 CTexture, CFont, CSFX, CBGM 등 다양한 리소스를 std::shared_ptr로 관리합니다. 덕분에 씬은 필요한 리소스의 소유권을 명확히 가지며, UnloadResources() 호출 시 벡터를 비워 참조를 모두 해제합니다. 스마트 포인터 기반 참조 관리로 사용하지 않는 리소스를 안전하게 정리할 수 있습니다.

void CSceneManager::SwapScene()
{
	CScene* newScene = GetSceneFromState(mPending.pendingState);
	newScene->LoadResources();
	
	CScene* oldScene = mScenes.back();
	if (oldScene->Exit())
	{
		oldScene->UnloadResources();
		SAFE_DELETE(oldScene);
		mScenes.pop_back();
	}
	
	mScenes.push_back(newScene);
	mScenes.back()->Enter(mPending.payload);
}

  • SwapScene()는 새로운 씬을 먼저 생성해 리소스를 로드한 뒤, 기존 씬을 Exit()하고 리소스를 언로드한 후 스택에서 제거합니다. 이 전환 과정에서는 이전 씬과 현재 씬이 공유하는 리소스를 재로드하지 않고 그대로 재사용하므로, 전환 지연을 최소화하고 메모리 사용 효율이 높아집니다.

맺는 말

CSceneManager씬 스택 구조스마트 포인터 기반 리소스 관리는 단순한 씬 교체를 넘어, 전환 과정의 안정성메모리 관리의 신뢰성을 높입니다. 이를 통해 다양한 씬 전환 패턴을 상황에 맞게 적용할 수 있으며, 프레임워크 전반에서 유연한 구조 확장장기적인 유지보수성을 지원합니다.