GameEngine 구조를 구성하기 위해 각각 GameObject, Resource라는 필수 핵심 클래스를 관리하는 해당 컨테이너를 선택하십시오. 그 이유는 전체 게임 엔진 프로세스 중에 각 중요한 함수 호출에서 발생한 실제 작업 (단일 항목 검색, 삽입 / 삭제, 트래버스)을 기반으로해야합니다.
STL map, unordered_map, Vector의 장단점 및 특징은 지난 포스팅에 블로깅 되어있습니다.
에디터작업(삽입삭제 빈번) -> 저장 -> 씬로딩-> 리소스로딩 -> 루프 (Update, Drawcall)
게임오브젝트 : Vector를 선택했습니다. 그 이유는 렌더링 처리를 하려면 다 돌아야 하는데 특정 물체를 집어서 가는게 아니라 처음부터 끝까지 다 돌아야 하기 때문입니다. 그렇기 때문에 삽입, 삭제, 탐색이 모두 O(n) 인 벡터를 골랐습니다.
리소스 : unodered_map을 선택했습니다. 그 이유는 씬로딩은 게임오브젝트를 로딩하는것이며 그것들은 위에서 말했듯
Vector로 관리가 될 것입니다. 또한, 그것들을 하나씩 순차적으로 로딩할 때 그것들이 가지고 있는 리소스가 무엇인지를 판단 한 후 그 안에 있는 포인트 정보(Key값)만 로딩하면 됩니다. 그러므로 에디터가 아닌 한 Key값이 정렬되어야 할 필요가 없기 때문에 비정렬에서 빠른 unordered_map을 선택했습니다.
Tip) 에디터에선 정렬되서 보여야하기 때문에 map이 최고의 성능을 발휘하지만 굳이 정렬 될 필요가 없다면
unordered_map을 써도 문제는 없다.
C ++ 언어에서 구조체와 클래스의 차이점에 대한 간단한 보고서를 작성하십시오.
구조체와 클래스의 차이점은 바로 접근법의 차이입니다. C++에서는 접근제어 지시자가 3가지 존재합니다.
어디서든 허용하는 public, 상속관계에서 허용하는 protected, 클래스 내에서만 허용하는 private가 있습니다.
구조체의 경우는 위 3가지를 따로 선언하지 않으면 모두 public으로 선언되며,
클래스의 경우는 위 3가지를 따로 선언하지 않으면 모두 private으로 선언됩니다.
Tip) C# 기준 Struct는 value type으로 stack memory에 생성되며, Class는 reference type으로 heep memory에 생성됨.
Math 라이브러리가 클래스 대신 struct를 사용하여 객체를 정의하는 이유를 생각하십시오.
제 생각에는 Class가 Struct 보다 더 우월하며 참조 타입인 클래스는 힙에 생성돼서 스택도 덜 차지하고 또한 상속과 다형성도 지원하기 때문에 Class를 쓰는것이 더 좋다고 생각이 듭니다. 하지만 Math Library에서는 Class대신 Struct를 사용했는데 그 이유유를 생각해보자면, Class의 장점들인 상속과 다형성이 필요없기 때문이 아닐까? 라고 생각합니다. 또한 매번 생성자를 정의하고 변수가 필요할 떄 마다 new를 호출하는 것은 매우 번거롭기 때문이지 않을까?라고 추측합니다.
다음 링크를 참조하여 프로그래밍 로직을 구현하십시오. https://www.notion.so/ideugu/6-fd8fa5b2889848fcbd9b8b77e71de7d1
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
struct Vector2
{
Vector2() = default;
float X = 0.f;
float Y = 0.f;
};
struct GameObjectMock
{
GameObjectMock(const std::string& InName) : Name(InName)
{
Hash = std::hash<std::string>()(Name);
}
std::size_t Hash;
std::string Name;
Vector2 v;
// 비교 연산자 ==, != 추가
inline bool operator==(const GameObjectMock& hs)
{
return Hash == hs.Hash;
}
inline bool operator!=(const GameObjectMock& hs)
{
return Hash != hs.Hash;
}
};
struct OrderByHash
{
inline bool operator () (const GameObjectMock& _left, const GameObjectMock& _right)
{
return _left.Hash < _right.Hash;
}
inline bool operator () (const GameObjectMock& _left, const std::hash<std::string>::result_type& _right) const
{
return _left.Hash < _right;
}
};
int main()
{
const auto startTime = std::chrono::high_resolution_clock::now();
std::vector<GameObjectMock> sorted;
std::vector<GameObjectMock> sizeCheck = { GameObjectMock("11"), GameObjectMock("111"), GameObjectMock("11111"), GameObjectMock("10"), GameObjectMock("1111") };
for (const GameObjectMock& n : sizeCheck)
{
auto it = std::lower_bound(sorted.begin(), sorted.end(), n, OrderByHash());
if (it != sorted.end() && *it != n)
{
sorted.insert(it, n);
}
else if (it != sorted.end() && *it == n)
{
// dup!!
continue;
}
else if (it == sorted.end())
{
sorted.push_back(n);
}
}
std::chrono::high_resolution_clock::duration elapsedTime = std::chrono::high_resolution_clock::now() - startTime;
std::cout << std::endl;
std::cout << "sorted_vector Time: " << std::chrono::duration_cast<std::chrono::nanoseconds>(elapsedTime).count() << " ns" << std::endl;
for_each(sorted.begin(), sorted.end(), [](GameObjectMock x) { std::cout << std::hex << x.Name << " "; });
std::cout << std::endl;
}
Notion에 있는 기존 코드에서 int로 sort 된 vector를 GameObjectMock으로 바꾸는 과정에서 아래와 같은 문제가 발생하여 비교연산자를 추가해주었습니다.
결과창
'게임제작기법연구' 카테고리의 다른 글
게임제작기법연구 8주차 (0) | 2020.06.02 |
---|---|
게임제작기법연구 7주차 (0) | 2020.05.26 |
게임제작기법연구 5주차 (0) | 2020.05.12 |
게임제작기법연구 4주차 (0) | 2020.05.05 |
게임제작기법연구 2주차 (0) | 2020.04.09 |