개발하는 리프터 꽃게맨입니다.

[C++] 이벤트 예약 및 함수 지연 처리 구현 본문

언어/C, C++

[C++] 이벤트 예약 및 함수 지연 처리 구현

파워꽃게맨 2024. 2. 9. 23:34

이것을 따로 부르는 개념이 있는지는 모르겠지만,

필요해서 연구를 하다보니 꽤나 쓸만한 개념인 것 같아서 포스팅 해봅니다.

 

 

대부분의 프로그램이 이런 방식으로 메인 루프가 존재합니다.

예를 들어서 우리가 게임을 만든다고 가정해봅시다.

 

그럼 플레이어가 화살을 쏜다고 하면 화살을 생성해야할 것 이고,

또 화살이 몬스터에게 닿으면 삭제를 해줘야 할 것 입니다.

 

그런데,

 

 

이런 식으로 루프 중간중간에 막 추가해버리면

코드가 꼬일 수 있습니다.

 

정확한 예시는 제시하긴 좀 애매하긴한데..

어쨌든 우리는 함수를 예약해서 지연 처리를 할 필요성이 있다는 겁니다. (좀 엉렁뚱땅 넘어가는 느낌이긴 하지만..)

 

 

중간 중간에

특히, 특정 메모리를 추가로 할당하거나 삭제할 때,

use-after-free 문제 등이 많이 발생하므로

 

이런 행위는 미리 예약을 걸어놓고 나중에 루프의 마지막에 한꺼번에 지연해서 처리해주는 것이 좋습니다.

 

여러가지 방법으로 지연처리를 한 번 구현해보도록 하죠!

 

기본 아이디어

처음에는 '함수 포인터'로 구현하는 것을 고려했습니다.

그러나 함수 포인터는 함수의 주소를 저장하는 것이기에 지연 처리는 추가적인 작업을 해야합니다.

 

넣고싶은 매개변수를 struct 라는 메시지로 압축한 다음에

(함수주소, 매개변수 압축)을 쌍을 큐에 저장하는 방법이죠.

 

이는 확실히 조금 번거롭습니다.

 

더하여, 동일한 매개변수, 동일한 반환형을 가지는 함수에 대해서만 처리할 수 있습니다.

유연성이 부족하죠.

 

그래서 저는 함수 객체가 더 적합하다고 생각합니다.

그 이유는 다음과 같습니다.

 

1) 함수 객체는 멤버를 가질 수 있기에, 객체 안에 매개변수를 포함시킬 수 있습니다.

2) 상속을 이용하면, 다른 매개변수에 대한 처리 또한 할 수 있습니다. (반환형은 동일해야 함)

 

위 아이디어를 통해 만들어낸 기본적인 지연 처리 구조에 대해서 보여드리겠습니다.

바로 이런 식으로

하나의 Event 라는 부모 클래스를 만들어서

필요한 Event를 파생시켜나가는 것이죠.

 

모든 Event는 객체로 만들어져있기 때문에

객체의 멤버 변수들을 입력하면, 같은 Event 객체라도 다른 매개변수를 받을 수 있게끔하는 효과를 줄 수 있습니다.

 

그리고 Event 포인터를 가지는 이벤트 큐를 두어서 나중에 지연처리를 하는 것이죠.

 

 

이런 식으로 

미리 호출할 함수를 객체로 만들어서 따로 큐에 예약을 해놓은 다음에

나중에 한꺼번에 지연 처리방식으로 하면, 시스템이 꼬이는 상황을 예방할 수 있습니다.