본문 바로가기

프로그래밍/TIL

자체 게임 엔진 개발하기 (HopStep Engine) - HeaderTool 만들기와 Property Get/Set 메서드 작성

 요즘 너무 게임만 하는 것 같아서, POE를 좀 정리하고 자체엔진 만드는 취미를 다시 조금씩 하고 있다.

 지난 번에 끝났던 상태는 리플렉션 구현인데, 그 상태에서 계속 이어서 진행해보았다.

 

 

 

 HeaderTool

 Unreal Header Tool의 역할을 해줄 프로젝트를 하나 만들었다. 언리얼은 BulidTool이 C#이고, HeaderTool은 C++로 구현되어있는데, 내 프로젝트에서는 그냥 편의를 위해 C#으로 구현했다. 당장에는 필요한 기능이 많지 않으므로, 유연해보이지 않더라도 최대한 가볍게 구현해보는 것이 목적이다.

 

 내 HeaderTool의 목적은 결국 엔진, 컨텐츠단의 오브젝트들의 정보를 읽고, 이를 지원하는 리플렉션 정보를 생성하는 것이다. 

 위와 같은 헤더를 읽고, Finite State Machine 같은 느낌으로 HCLASS가 있구나, PROPERTY가 선언되어 있구나, 그 타입은 뭐구나를 읽어들이는 것이다. 이렇게 수집해놓은 스키마를 바탕으로 generated.h와 generated.cpp를 새로 작성해준다.

 

 Generated.cpp는 위와 같은 코드를 만들어준다. 각 클래스의 __Fill_Class_Property_류의 코드는 static 타임에 실행이 되고, AddProperty 메서드를 통해 HClass에 프로퍼티의 정보를 미리 넣어주는 역할을 수행해준다.

 IMPLEMENT_CLASS 매크로는 __Fill_Class_Property_를 실행시켜주는 Static Auto Initializer 선언과 StaticClass 메서드를 구현해두고 있는 매크로다.

 

AddProperty에서는 들어온 필드의 Class 오프셋과 사이즈를 측정하여 Property 정보를 채워주고 만들어서 넣어주는 역할을 수행한다. 여기까지 진행이 되었다면 이제 런타임에 어떤 클래스가 어떤 프로퍼티를 들고 있는지에 대한 간략한 정보는 알 수 있게 된 것이다.

 

 

 TestCase를 보며 좀 확인을 해보자면, 어떤 클래스의 Static GetPropertyValue 메서드를 이용해 해당 프로퍼티의 값을 얻어올 수 있고, ChangePropertyValue 메서드를 통해 해당 프로퍼티의 값을 변경할 수 있다.

 

 각각의 메서드들은 함수 인자로 들어온 프로퍼티의 이름을 통해 Property 정보를 찾아온다. Property 객체는 해당 프로퍼티가 클래스 메모리 레이아웃의 얼마만큼의 Offset으로부터 얼마만큼의 Size로 위치해있는지를 기록해 놓은 것이기 때문에, 결국 Instance의 포인터를 이용하면 해당 프로퍼티의 메모리에 접근할 수 있겠다는 생각이었다.

 

 

 다음 구현 목표는 지난 포스트에서도 언급했던 프로퍼티 체인을 만들고, 이를 이용해 클립보드 Serialize를 하는 것이다.

 그리고 지금은 멤버만 프로퍼티 시스템을 구현해두었는데, 메서드에 대해서도 프로퍼티를 만들어볼까 싶다.

 파이팅