部屋から出る

transactLeaveRoom, doLeaveRoom

部屋から出る時は transactLeaveRoom が呼ばれ、 この関数の中からさらに doLeaveRoom が呼ばれる。カスタマイズは doLeaveRoom のオーバーライドで行う。


inline void RoomModule::transactLeaveRoom(SessionHandle& hSession)
{
   Room* pRoom = hSession.domain()->room();
   if (! pRoom) { return; }

   pRoom->lock();
   {
      doLeaveRoom(pRoom, hSession);
   }
   pRoom->unlock();
}

退室は基本的にはフレームワークから呼ばれるが、アプリケーション主導で呼びたいケースもある。 このような場合には、transactLeaveRoom() を呼ぶ。

doLeaveRoom

doLeaveRoom では、退室処理を実装する。

void SampleRoomModule::doLeaveRoom(Room* _pRoom, SessionHandle& _hSession)
{
   SampleRoom* pRoom = static_cast< SampleRoom* >(_pRoom);
   SessionHandle hSession(_hSession);
   if (! pRoom->leave(hSession)) {
      return;
   }

   {
      LeaveRoomNotify* pRes = new LeaveRoomNotify();
      pRes->domainIndex = hSession.domain()->index();
      hSession.session()->queueMessage(pRes);
   }

   if (0 == pRoom->countMembers()) {
      pRoom->close();
   } else {
      notifyRoom(pRoom);
   }
}

SampleRoom::leave 呼び出し

実際に入室情報を更新するのは SampleRoom::leave で実装しているので、これを呼ぶ。

   SampleRoom* pRoom = static_cast< SampleRoom* >(_pRoom);
   SessionHandle hSession(_hSession);
   if (! pRoom->leave(hSession)) {
      return;
   }

ここで、引数に与えられた SessionHandle は参照渡しになっているので、どこ由来のものか分からない。 もしかしたら、Room が内部で持っているものかもしれない。

Room が持っている SessionHandle は、当然ながら Room が自由に扱える。leave() 呼び出しで中身が変更されるかもしれない。そうなると、その SessionHandle はもう使えなくなる。

このようなケースを避けるため、引数の SessionHandle はそのまま使わずにコピーして使っている。

SampleRoom::leave

leave は退室処理を行う関数である。

bool SampleRoom::leave(const SessionHandle& hSession)
{
   lock();
   bool b = removeMember(hSession);
   unlock();
   return b;
}

単に removeMember() を呼んでいるだけである。

removeMember は、ベースクラス Room で実装されている関数で、部屋のメンバーから削除する。 また、DomainContext の部屋情報もクリアする。

LeaveRoomNotify

退室処理を終えたら、LeaveRoomNotify を送信する。

   {
      LeaveRoomNotify* pRes = new LeaveRoomNotify();
      pRes->domainIndex = hSession.domain()->index();
      hSession.session()->queueMessage(pRes);
   }

RoomInfoNotify

まだ部屋に人がいる場合、残っている人に RoomInfoNotify を投げる。

   if (0 == pRoom->countMembers()) {
      ...
   } else {
      notifyRoom(pRoom);
   }

閉室処理

このサンプルでは、部屋に人がいなくなったら閉室とする。 そのため、退室後に部屋の人数を確認し、ゼロ人ならば transactCloseRoom を呼ぶ。

   if (0 == pRoom->countMembers()) {
      transactCloseRoom();
   }

transactCloseRoom については、閉室処理で詳しく説明する。