[게임 프로그래밍 패턴] 16. 데이터 지역성 패턴

WIGWAG·2023년 3월 20일

CPU 캐시를 최대한 활용할 수 있도록 데이터를 배치해 메모리 접근 속도를 높인다.

#include <cassert>

class Entity {
public:
	void update();
	void activeRender(int index);
	void deactiveRender(int index);
private:
	const int MAX_ENTITIES = 10;

	//객체포인터를 사용하는 것보다 컴포넌트를 배열로 만드는 것이 캐시미스가 적게 일어나 50배정도 더 빠르다.
	AIComponent* aiComponents = new AIComponent[MAX_ENTITIES];
	PhysicsComponent* physicsComponents = new PhysicsComponent[MAX_ENTITIES];
	
	int numActive_;
	//배열에서 활성화된 것들을 앞쪽에 모아두기
	RenderComponent* renderComponents = new RenderComponent[MAX_ENTITIES];
};

//빈번하게 쓰이는 코드
class AIComponent {
public:
	void update() {}
private:
	Animation* animation_;
	double energy_;
	Vector goalPos;
	LootDrop* loot_;
};

// 한 번만 쓰이는 코드 : 죽었을 때 전리품 드랍
class LootDrop {
	friend class AIComponent;
	LootType drop_;
	int minDrops_;
	int masDrops_;
	double chanceOfDrop_;
};

class PhysicsComponent {
public:
	void update() {}
};

class RenderComponent {
public:
	void render() {}
};

void Entity::update() {
	while (!gameOver)
	{
		for (int i = 0; i < MAX_ENTITIES; i++)
		{
			aiComponents[i].update();
		}

		for (int i = 0; i < MAX_ENTITIES; i++)
		{
			physicsComponents[i].update();
		}

		for (int i = 0; i < numActive_; i++)
		{
			renderComponents[i].render();
		}
	}
}

void Entity::activeRender(int index){
	//비활성화된 원소여야 한다.
	assert(index >= numActive_);

	// 새로 활성화된 원소를 비활성 원소 중 맨 앞에 있는 것과 바꿔서 활성 원소 중에서 맨 뒤에 가게 한다.
	RenderComponent temp = renderComponents[numActive_];
	renderComponents[numActive_] = renderComponents[index];
	renderComponents[index] = temp;

	// 이제 활성화 원소가 하나 늘었다.
	++numActive_;
}

void Entity::deactiveRender(int index) {
	//활성화된 원소여야 한다.
	assert(index < numActive_);

	// 이제 비활성화 원소가 하나 늘었다.
	--numActive_;

	// 새로 활성화된 원소를 비활성 원소 중 맨 앞에 있는 것과 바꿔서 활성 원소 중에서 맨 뒤에 가게 한다.
	RenderComponent temp = renderComponents[numActive_];
	renderComponents[numActive_] = renderComponents[index];
	renderComponents[index] = temp;
}
profile
프로그래밍 공부 기록 노트

0개의 댓글