이제 BroadCast와 같은 LOCK이 걸릴만한 이벤트처리에서 Job을 사용한다
bool Handle_C_CHAT(PacketSessionRef& session, Protocol::C_CHAT& pkt)
{
std::cout << pkt.msg() << endl;
Protocol::S_CHAT chatPkt;
chatPkt.set_msg(pkt.msg());
auto sendBuffer = ClientPacketHandler::MakeSendBuffer(chatPkt);
// Job에 밀어넣자
GRoom.PushJob(MakeShared<BroadcastJob>(GRoom, sendBuffer));
return true;
}
int main()
{
// Job의 처리는 main에서 하고있음
while (true)
{
GRoom.FlushJob();
this_thread::sleep_for(1ms);
}
GThreadManager->Join();
}
class Room
{
friend class EnterJob;
friend class LeaveJob;
friend class BroadcastJob;
private:
// 싱글쓰레드 환경인마냥 코딩
void Enter(PlayerRef player);
void Leave(PlayerRef player);
void Broadcast(SendBufferRef sendBuffer);
public:
// 멀티쓰레드 환경에서는 일감으로 접근
void PushJob(JobRef job) { _jobs.Push(job); }
void FlushJob();
private:
map<uint64, PlayerRef> _players;
JobQueue _jobs;
};
이렇게 쉽게 모든게 해결됐을까?
지금은 Enter
, Leave
, Broadcast
만 처리한는데 또 다른 함수가 생긴다면? 가령 Move??
또 함수를 만들고 Job을 또 만들어야하나? 이거 실수할 여지가 많은데??
// 이런걸 또 만들어야 한다고??
class EnterJob : public IJob
{
public:
EnterJob(Room& room, PlayerRef player) : _room(room), _player(player)
{
}
virtual void Execute() override
{
_room.Enter(_player);
}
public:
Room& _room;
PlayerRef _player;
};
이걸 개선해보자