본문 바로가기
Develop/Win32 API와 게임 엔진

[개발] 공부하며 정리한 "Singleton 패턴"과 Core 객체

by Tarra 2023. 10. 20.

 

 

 


개인 공부 후 자료를 남겨놓기 위한 목적이므로,
생략되거나 오류가 있을 수 있음을 알립니다.

잘못된 부분이 있다면 댓글로 상냥하게 가르쳐주시면 감사하겠습니다!

 

 

Win32 api를 통해 게임엔진을 구현해 보면서 Singleton 패턴이 무엇이고, 이 패턴을 이용해 무엇을 구현하는지 알아보도록 하자. 

 

 

 

보며 공부한 곳! // 어소트락 아카데미 Win32 API 무료강의

https://youtu.be/dlFr-OnHlWU?si=K8UpK8CwSOddqFZ5


 

win32를 조금 공부해보신 분이라면 다음의 코드가 어떤 것을 의미하는지 알 수 있을 것이다.

 

해당 부분은 wWinMain 함수의 일부분으로

 

while문에서 GetMessage를 통해 메시지를 계속해서 기다리고 있다가,

 

우리가 프로그램에게 어떠한 메세지를 주게 되면, 그에 따른 행동을 하게 하는 루프문이다.

 

이 구조의 특징은 메시지가 발생해야 그 후 일을 처리한다는 것이다.

 

 

 

우리가 게임을 플레이할 때 일부 특정한 장르를 제외하고는 아무것도 하지 않아도 인게임 내의 시간은 계속 흘려가기 마련인데

 

이 구조를 그대로 사용하게 되면 입력을 받을 때만 인게임 내의 시간이 흘러가게 된다.

 

따라서 이를 해결하기 위해 우리는 심장을 만들어 프로그램을 관리시키게 된다.

 

이 문서에서는 이 심장이 되는 객체를 Core라고 하겠다.

 

해당 객체를 만들기 위해 Core class를 만들어주겠다.

 

 

프로그램이 실행되고 종료될 때까지 심장은 단 하나만 존재해야만 한다.

 

프로그램이 작동하는 도중에 Core객체가 중간에 새로 생성되거나, 삭제되게 되면 큰일이 나게 되므로

 

해당 클래스가 단 하나의 객체만을 가지도록 보장하고, 전역적인 접근을 가능하게 해야하는데 이를 뜻하는 디자인 패턴이 바로

 

Singleton 패턴이 되시겠다.

 

core 클래스의 역할 (싱글톤 패턴의 역할)

1. 게임 시스템 전체를 관장

2. 게임 시스템의 전역 변수

3. 씬 로드 시 데이터가 파괴되지 않고 유지

4. 여러 오브젝트가 접근할 수 있는 데이터 활용

(출처 : https://stickode.tistory.com/178 )

 

 

그렇다면 Core 클래스를 싱글톤으로 구현해 보도록 하자.

 

가장 기본인 Core 클래스의 구현은 다음과 같이 작성된다.

 

 

가장 핵심이 되는 키워드는 static이다. 

 

static 키워드는 정적 데이터의 선언으로 함수가 호출될 때마다 초기화되지 않고 프로그램이 종료될 때까지 데이터가 유지되게 된다.

 

따라서 CCore mgr은 컴파일 타임에 선언되어 프로그램이 종료될 때까지 존재하게 되고, 

 

우리는 GetInst() 라는 메서드를 통해 해당 객체에 언제든지 접근이 가능하게 된다.

 

 

 

이번엔 init(), progress() 멤버 함수에 대해 알아보자.

 

이 두 함수는 어려울 것이 없다. init() 멤버 함수는 프로그램이 처음 실행될 때 호출하여 Core 객체에 필요한 변수들을 저장한 뒤,

 

객체가 정상적으로 잘 초기화 되었는지 판단하는 용도의 함수이다.

 

 

progress() 멤버 함수는 위의 while에 삽입되어 다음과 같이 구현된 뒤, 프로그램이 매 순간마다 특정한 행동을 할 수 있도록 도와주는 역할을 하게 된다.

 

루프가 시작되기 전 init()을 한 후 루프에서 progress()를 반복적으로 실행하게 된다.

 

GetMessage()에 관하여

GetMessage()가 PeekMessage()로 대체된 이유는 다음과 같다.
GetMessage()의 경우 메세지가 들어올 때까지 대기하는 동작을 하지만,
PeekMessage()의 경우에는 메세지가 들어오지 않아도 계속 동작을 하며 메세지를 기다린다는 특징이 있다.

우리는 우리가 아무것도 하지 않아도 프로그램의 시간이 흐르는 것을 원하고 있기 때문에 GetMessage()가 아닌
PeekMessage()를 사용하게 된다.

 

이제 싱글톤을 이용하여 게임의 심장인 Core를 구현해보았다.

 

우리는 해당 Core를 이용하여 Core에 갖가지 매니저들을 구현하여 프로그램이 원활히 작동할 수 있도록 할 것이다.

 

 

다음은 키 입력을 받아보고, 게임의 심장박동인 프레임을 구현하는 DeltaTime에 대해서 알아보도록 하자.