[게임 프로그래밍 패턴] 14. 이벤트 큐 패턴

WIGWAG·2023년 3월 18일

메시지나 이벤트를 보내는 시점과 처리하는 시점을 디커플링한다.

#include <iostream>
#include <cassert>

using namespace std;

enum SoundId {
	SOUND_A
};

struct PlayMessage {
	SoundId id;
	int volume;
};

class Audio {
public:
	static void init() {
		head_ = 0;
		tail_ = 0;
	}

	static void PlaySound(SoundId id, int volume);
	static void Update();
	//그 외 메서드
private:
	static int head_;
	static int tail_;
	
	static const int MAX_PENDING = 16;
	static PlayMessage pending_[MAX_PENDING];
	static int numPending_;
};

void Audio::PlaySound(SoundId id, int volume) {
	//보류 중인 요청을 쭉 살펴본다.
	for (int i = head_; i != tail_; i = (i + 1) % MAX_PENDING)
	{
		if (pending_[i].id == id) {
			//둘 중에 소리가 큰 값으로 덮어쓴다.
			pending_[i].volume = max(volume, pending_[i].volume);
			//이 요청은 큐에 넣지 않는다.
			return;
		}
	}

	assert((tail_ + 1) % MAX_PENDING != head_);

	//배열 맨 뒤에 추가한다.
	pending_[tail_].id = id;
	pending_[tail_].volume = volume;
	tail_ = (tail_ + 1) % MAX_PENDING;
}

void Audio::Update() {
	//보류된 요청이 없다면 아무것도 하지 않는다.
	if (head_ == tail_) return;

	ResourcedId resource = loadSound(pending_[head_].id);
	int channel = findOpenChannel();
	if (channel == -1) return;

	startSound(resource, channel, pending_[head_].volume);
	head_ = (head_ + 1) % MAX_PENDING;
}

int main() {
	Audio::PlaySound(SOUND_A, 100);
    Audio::Update();
}
profile
프로그래밍 공부 기록 노트

0개의 댓글