game dev/directX 3D

DirectX 3D 5일차 - 키보드 클래스(Keyboad Class)

onue 2021. 4. 12. 00:28

www.youtube.com/watch?v=h7HCdEyGRRw&list=PLqCJpWy5Fohd3S7ICFXwUomYW0Wv67pDD&index=9

Keyboard 클래스는 Window 클래스에 접근할 수 있고 Event라는 클래스를 가지고 있습니다.

키보드의 입력과 처리를 위한 클래스인 Keyboard 클래스입니다.

키보드 클래스 안에는 키보드가 눌렸을 때 처리하기 위한 Event 클래스부터 알아보겠습니다.

 

Event Class

Type - 키보드 이벤트가 어떤 상황에서 발생했는지를 지정하기 위한 열거형 변수 타입.

Press - 키보드가 눌렸을 때 발생하는 이벤트

Release - 키보드가 눌렸다가 다시 띄워젔을때 발생하는 이벤트

Invalid - 유효하지않은 키보드를 눌렀을 때

 

Type type

 - 해당 이벤트가 어떤 이벤트인지를 지정하기 위한 변수.

 

unsigned char code

 - 어떤 키보드가 눌렸는지를 파악하기 위한 키코드를 담을 변수.

 

Event()
 - Event class 기본 생성자이고 아무 전달 인자 값이 없을 경우 기본적인 타입은 Invalid 타입이고

code는 0u로 지정을 하게 됩니다.

 

Event(Type type, unsigned char code)

 - Event class 전달 인자값이 있을 경우 해당 인자 값을 클래스 변수 code, type에 할당해 주게 됩니다.

 

bool IsPressed()
 - 키보드가 눌렸는지를 판단하기 위해서 type 변수의 값이 press 상태인지를 확인하는 변수입니다.

 

bool IsRelease()
 - 키보드가 띄어진 상태를 확인하기 위해서 type 변수의 값이 Release 상태인지를 확인하는 변수입니다.

 

bool IsValid()
 - 키보드가 유효한 상태인지를 확인하기 위해서 사용하는 함수입니다. 단 여기서는 유효한 상태임을 확인하기 위해서

type 변수가 InValid가 아닌 상태 즉 Release나 Press 상태인지를 검사하는 것입니다.

 

unsigned char GetCode()
 - 해당 Event의 코드 값을 반환하는 함수입니다.

 

Keyboard Class

Keyboard() = default

 - 컴파일러가 생성해주는 기본적인 생성자를 사용하겠다는 의미입니다. Keyboard() {}와 동일

 

Keyboard(const Keyboard&) = delete

Keyboard& operator=(const Keyboard&) = delete

 - 컴파일러가 생성해주는 기본적인 생성자를 사용하지 않겠다는 의미입니다.

복사 생성자를 방지하기 위해서 사용하고 있습니다. 

Keyboard kb1;

Keyboard kb2(kb); // error발생

또는 kb1 = kb2 // error 발생

 

static constexpr unsigned int nKeys = 256u

 - 키보드가 눌려있는지를 파악하기 위한 비트의 개수

 

static constexpr unsigned int bufferSize = 16u

 - 한번에 처리할 수 있는 event buffe의 사이즈를 지정해서 event가 밀리는 것을 방지할 수 있습니다.

 

bool autorepeatEnabled = false

 - 반복적으로 한 키보드가 눌리는 것을 방지하기 위한 변수인 것 같은데 이 변수는 한번 쓰임새를

보아야만 완벽히 이해할 수 있을것 같습니다.

 

std::bitset<nKeys> keystates

 - 아까 위에서 생성한 키 상태 크기만큼의 비트 배열을 지정해서 해당 키가 눌렸을 때 그 자리의 bit를 1(true)로 바꾸어서

Keyboard에서 어떤 키가 눌렸는지를 확인할 수 있게 해 줍니다.

 

std::queue<Event> keybuffer

 - Queue 자료구조는 FIFO(First In Firest Out)이므로 Event를 담아놓고 처리하기에 유용합니다. Event를 계속 Queue에 넣고

넣어진 순서대로 처리하게 됩니다.

 

std::queue<Event> charbuffer

 - 만약 F1이나 Shift, Alt, Ctrl 키 말고 문자를 가지고 있는 키보드 값을 Queue로 넣어서 처리하는 변수입니다.

 

bool KeyIsPressed(unsigned char keycode) const noexcept

 - 인자로 넘겨준 키보드 값이 눌렸는지를 확인해주는 함수입니다.

 

Event ReadKey() noexcept

 - Event가 담겨있는 Queue로부터 Event 1개를 Pop을 해서 반환해주는 함수입니다.


bool KeyIsEmpty() const noexcept

 - Event가 담겨있는 Queue가 비었는지를 판단하는 함수입니다.


void FlushKey() noexcept

 - Event가 담겨있는 Queue를 깨끗하게 모두 삭제하는 함수입니다.

 

char ReadChar() noexcept

 - char 자료형이 담겨있는 Queue에서 데이터를 하나 Pop후 처리하기 위해 반환해주는 함수입니다.


bool CharIsEmpty() const noexcept

 - char가 담겨있는 Queue가 비었는지를 판단하는 함수입니다.


void FlushChar() noexcept

 - char가 담겨있는 Queue를 깨끗하게 모두 삭제하는 함수입니다.

 

void Flush() noexcept

 - char가 담겨있는 Queue와 Event가 담겨있는 Queue를 모두 깨끗하게 정리하기 위한 함수입니다.

위에서 언급한 FlushChar(), FlushKey() 함수가 안에 할당되어 있습니다.

 

void EnableAutorepeat() noexcept

 - 클래스 변수인 autorepeatEnabled가 true인지를 반환하는 함수입니다.

 

void DisableAutorepeat() noexcept

 - 클래스 변수인 autorepeatEnabled가 false인지를 반환하는 함수입니다.

 

bool AutorepeatIsEnabled() noexcept

 - 클래스 변수인 autorepeatEnabled가 어떤 상태인지를 반환하는 함수입니다.

 

void OnKeyPressed(unsigned char keycode) noexcept

 - 함수 인자 값으로 전달된 keycode를 가지고서 keystate에서 해당 keycode가 눌렸으므로 true로 바꾸어 줍니다.

그리고 해당 키가 눌렸으므로 Event 변수를 생성하는데 생성자를 통해서 Type을 Press로 할당하고 keycode를 통해서

Event 변수를 생성 후 Queue에 넣어주게 됩니다.

단, 밑에서 설명할 TrimBuffer를 통해서 해당 queue의 size가 bufferSize보다 작아질 때까지 Pop을 해서 Event를 처리하게

해주게 됩니다.

 

void OnKeyReleased(unsigned char keycode) noexcept

 - 함수 인자값으로 전달된 keycode를 가지고서 keystate에서 해당 keycode가 띄워젔으므로 false로 다시 바꾸어 줍니다.

그리고 해당 키가 띄워젔으므로 Event 변수를 생성하는데 생성자를 통해서 Type을 Release로 할당하고 keycode를 통해서

Event 변수를 생성 후 Queue에 넣어주게 됩니다.

단, OnKeyPressed와 마찬가지로 TrimBuffer를 통해서 해당 queue의 size가 bufferSize보다 작아질 때까지 Pop을 해서 Event를 처리하게 해주게 됩니다.

 

void OnChar(char character) noexcept

 - 인자로 전달된 문자를 Queue에 넣어주게 됩니다. 또한 마찬가지로 TrimBuffer를 통해서 해당 queue의 size가 bufferSize보다 작아질 때까지 Pop을 해서 Event를 처리하게 해주게 됩니다.

 

void ClearState() noexcept

 - keystate를 리셋해서 모두 false로 만들어줍니다.

 

template<typename T>

static void TrimBuffer(std::queue<T>& buffer) noexcept

 - 아까 위에서 여러번 언급했듯이 TrimBuffer 함수는 typename을 통해서 인자값을 전달된 여러 유형의 queue를

bufferSize보다 아래만큼 pop을 해서 size를 줄여주는 함수입니다.