728x90

1. 이벤트 큐 패턴 정의

  • 메시지나 이벤트를 보내는 시점과 처리하는 시점을 디커플링 하는 패턴
  • 게임 시스템들이 디커플링 상태를 유지한 채로 서로 고수준 통신을 하고 싶을 때 사용한다.

 

2. 원형 버퍼를 이용한 이벤트 큐 패턴 구현

struct PlayMessage
{
    SoundId Id;
    int Volume;
};

class Audio
{
private:
    static int Head;
    static int Tail;

    static const int MAX_PENDING = 16;
    static PlayMessage Pending[ MAX_PENDING ];

public:
    static void Init()
    {
        Head = 0;
        Tail = 0;
    }

     static void PlaySound( SoundId InId, int InVolume )
     {
        // 동일한 소리의 경우, 파장이 커지는 문제가 있어 요청 취합
        // 보류 중인 요청을 쭉 살펴본다.
        for ( int index = Head; index != Tail; index = ( index + 1) % MAX_PENDING )
        {
            if ( Pending[ index ].Id != InId )
                continue;

            // 둘 중 소리가 큰 값으로 덮어쓴 뒤, 큐에 넣지 않는다.
            Pending[ index ].Volume = max( InVolume, Pending[ index ].Volume );
            return;
        }

        // Tail값이 Head를 덮는 경우를 방지한다.
        if ( ( Tail + 1 ) % MAX_PENDING == Head )
            return;

        Pending[ Tail ].Id  = InId;
        Pending[ Tail ].Volume = InVolume;

        //원형 버퍼를 위해 Tail 조정
        Tail = ( Tail + 1 ) % MAX_PENDING;
     }


     static void Update()
     {
        // 보류된 요청이 없다면 아무것도 하지 않는다.
        if ( Head == Tail )
            return;
        
        ResourceId resourceId = LoadSound( Pending[ Head ].Id );
        int channel = FindOpenChannel();
        if ( channel == -1 )
            return;

        StartSound( resource, channel, Pending[ index ].Volume );
        
        //원형 버퍼를 위해 Head 조정
        Head = ( Head + 1 ) % MAX_PENDING;
     }
};
  • 요청 시점과, 처리 시점을 분리하여 게임 루프 혹은 별도 오디오 스레드에서 Update()를 호출하도록 구현
  • 요청 취합은 요청을 처리하는 시점 Update()에서 진행할 수 도 있다.

 

반응형

+ Recent posts