지금 게임 클라이언트 쪽 로직임. 컴포넌트 + 메시지 통신 사용하려고 함.
1. 인풋을 받으면 메인 메시지 큐에 메시지를 보냄.
2. 메인 메시지 큐는 메시지를 브로드캐스팅 함(정확히는 사전에 구독자를 설정해놓음. 중요하진 않으니 패스함).
3. 컴포넌트 매니저는 메시지를 받고 클라이언트에서 짜여진 로직에 따라 메시지를 처리함. 만약 해당 메시지 처리로 인해 다른 컴포넌트에 변화가 생겨야 하는 경우, 메인 메시지 큐로 메시지를 보냄.
그런데 내가 궁금한건 이게 비동기로 처리될 수 있는가임.
만약 이게 싱글스레드로 돌게 된다면,
1. 메인 메시지 큐가 브로드 캐스팅
2. 메시지를 받은 컴포넌트 매니저가 메시지를 처리. 그런데 다른 컴포넌트에 변화가 있어야 해서 다시 메시지 큐에 새로운 메시지를 보냄.
3. 메인 메시지 큐는 컴포넌트 매니저가 보낸 메시지를 또 브로드캐스팅
4. 반복
5. 메인 메시지 큐의 다음 메시지 처리.
이렇게 하나의 메시지는 여러 메시지를 낳고, 그 메시지간에 순서가 존재하게 됨.
이걸 멀티스레드로 돌릴 수 있는지 모르겠음... 구조를 잘못잡은건가 싶기도 하고.
만약 메인 메시지 큐에 피격 이벤트와 힐 이벤트가 들어왔다고 생각해보겠음.
1. 피격 이벤트 브로드캐스팅
2. HP 컴포넌트 메시지 받고 처리. 그런데 피가 0 이하가 됨.
3. Dead 컴포넌트 메시지 받고 처리. 이제 나는 죽은 상태임.
4. 힐 이벤트 브로드캐스팅
5. HP 컴포넌트 메시지 받음. 죽었는지 확인하기 위해 Dead 컴포넌트에게 죽었는지 알려달라는 메시지 전송
6. Dead 컴포넌트는 죽었다고 다시 메시지 전송
7. HP 컴포넌트는 해당 오브젝트가 죽었음을 알고 HP 증가를 하지 않음.
그런데 만약 메인 메시지 큐가 비동기적으로 들어오는 메시지마다 브로드캐스팅을 한다면
1. 피격 이벤트 브로드캐스팅
2. 힐 이벤트 브로드캐스팅
3. HP 컴포넌트의 메시지 큐에는 피격, 힐 메시지가 들어 있음.
4. 피격 메시지 처리해서 피가 0 이하가 됨. Dead 컴포넌트에게 죽여달라는 메시지 보냄.
5. 그 다음 힐 메시지를 바로 처리.(아직 Dead 컴포넌트에게 메시지가 오지 않음. 왔다고 해도 힐 메시지가 우선인 경우가 생김)
6. 힐을 받았더니 HP가 음수에서 양수로 변함.
7. 결국 오브젝트는 HP가 양수이지만 죽은 상태가 됨.
물론 이 경우에는 Dead 컴포넌트가 죽였다는 메시지 보내면 HP 컴포넌트가 피를 0으로 세팅하면 되긴 함.
그런데 그게 중요한게 아니라 이렇게 순서가 존재하는데 비동기로 처리할 수 있는가임... 존나어렵다...
순서가 중요하면 비동기를 쓰면 안됨 - dc App
헉 그렇군요. 감사합니다 ㅠ
그리고 3번에서 컴포넌트가 보낸 메세지를 브로드캐스팅 한다는데, 큐에 쌓아놓고 현재 메세지가 전부 전달된 다음 다음 큐 메세지를 처리하는게 맞는듯 - dc App
메세징 시스템 자체가 궁금하다면 akka - dc App
게임 클라이언트에서 병렬을 통한 고성능을 원한다면 Entity component system 을 찾아보는걸 추천함 - dc App
A 메시지를 브도르캐스팅 했을 때, 여러 컴포넌트 매니저가 받을 수 있고 그러면 메인 메시지 큐는 여러 메시지를 받을 수 있으니까 그걸 모아놓고 처리하라는거죠?
A 메시지로 인해 생긴 다른 메시지를 전부 처리하고, 메인 메시지 큐에 있는 다음 메시지 B를 처리한다. 이런건가요??
그게 아니고 2번 설명에 "다시 메세지 큐에 새로운 메세지를 보냄" -> 3번 설명에 "컴포넌트 매니저가 보낸 메세지를 브로드캐스팅" 이걸 보면 현재 메세지의 전파가 모든 컴포넌트에 되지 않았는데, 새로운 메세지를 전파하겠다는걸로 보고 이러면 안된다는 말이었음 - dc App
후자가 맞음 - dc App
아하 감사합니다. 덕분에 머리아플 일 하나 줄였네요 ㅎㅎ
erlang
비동기부터 뭔지 알고와라