[게임 프로그래밍 패턴] 18. 객체 풀 패턴

WIGWAG·2023년 3월 20일

객체를 매번 할당, 해제하지 않고 고정 크기 풀에 들어 있는 객체를 재사용함으로써 메모리 사용 성능을 개선한다.

#include <cassert>

class Particle {
public:
	void Init(double x, double y, double xVel, double yVel, int lifetime);
	bool Animate();
	bool InUse() const { return framesLeft_ > 0; }
	Particle* GetNext() const { return state_.next; }
	void SetNext(Particle* next) { state_.next = next; }

private:
	int framesLeft_ = 0;

	union {
		//사용 중일 때의 상태
		struct{
			double x, y;
			double xVel, yVel;
		} live;

		//사용 중이 아닐 때의 상태
		Particle* next;
	} state_;
};

void Particle::Init(double x, double y, double xVel, double yVel, int lifetime) {
	state_.live.x = x;
	state_.live.y = y;
	state_.live.xVel = xVel;
	state_.live.yVel = yVel;
	framesLeft_ = lifetime;
}

bool Particle::Animate() {
	if (!InUse()) return;

	--framesLeft_;
	state_.live.x += state_.live.xVel;
	state_.live.y += state_.live.yVel;

	return framesLeft_ == 0;
}

//빈칸 리스트 기법 : 사용할 때 리스트에서 꺼내오고 사용끝나면 리스트에 추가한다.(객체 재사용하여 메모리 할당/헤제줄이기)
class ParticlePool {
public:
	ParticlePool() {}
	void Create(double x, double y, double xVel, double yVel, int lifetime);
	void Animate();

private:
	static const int POOL_SIZE = 100;
	Particle particles_[POOL_SIZE];

	//헤드
	Particle* firstAvailable_;
};

ParticlePool::ParticlePool() {
	//처음 파티클부터 사용 가능하다.
	firstAvailable_ = &particles_[0];

	//모든 파티클은 다음 파티클을 가리킨다.
	for (int i = 0; i < POOL_SIZE - 1; i++){
		particles_[i].SetNext(&particles_[i + 1]);
	}

	//마지막 파티클에서 리스트를 종료한다.
	particles_[POOL_SIZE - 1].SetNext(nullptr);
}

void ParticlePool::Create(double x, double y, double xVel, double yVel, int lifetime){
	//풀이 비어 있지 않은 지를 확인한다.
	assert(firstAvailable_ != nullptr);

	//얻은 파티클을 빈칸 목록에서 제거한다.
	Particle* newParticle = firstAvailable_;
	firstAvailable_ = newParticle->GetNext();

	newParticle->Init(x, y, xVel, yVel, lifetime);
}

void ParticlePool::Animate(){
	for (int i = 0; i < POOL_SIZE; i++){
		if (particles_[i].Animate()) {
			// 방금 죽은 파티클을 빈칸 리스트 앞에 추가한다.
			particles_[i].SetNext(firstAvailable_);
			firstAvailable_ = &particles_[i];
		}
	}
}
profile
프로그래밍 공부 기록 노트

0개의 댓글