Room
========

见于 ``src/server/room`` 。需要动态创建和释放。可能受Lua依赖。

没持有着其他动态分配释放的类型。

对象创建和管理者
-------------------

都是RoomManager。

当Lobby收到 ``CreateRoom`` 后，调用RoomManager的接口创建房间。
房间在RoomManager中通过 ``std::map<int, std::shared_ptr<Room>>`` 管理。

使用场景
-------------

- 为大厅分担玩家，玩家不能同时在大厅和房间。
- 为运行在Lua中的房间提供支持。

释放时机
-------------

不被Lua需要，且房间内不存在socket存活的Player。

实现详情
-------------

关于被Lua需要
~~~~~~~~~~~~~~~~~~

房间有个受mutex保护的 ``lua_ref_count`` ，保存Lua的引用计数。当引用计数大于0就不能释放。

当房主按下“开始游戏”后，调用 ``Room::manuallyStart()`` ，此时Room必须绑定一个RoomThread，
若满足这一点则游戏开始，引用计数应该立刻+1。

.. warning::

   假设Lua一侧的寻找房间和开始游戏必定成功。这里没有错误处理，需要服主把关

当游戏结束后，Lua代码负责减少引用计数。Lua首先将Lua room删除，然后通过rpc调用方法
令房间的引用计数-1（可以认为立刻生效）。引用计数减为0时进行可释放检查。

关于是否存在人类
~~~~~~~~~~~~~~~~~~~~

在Lua计数为0的前提下，若房间内不存在人类了，则认为应该释放。

因为Lua中也有房间无人则GameOver的机制，因此当房内最后一名人类消失时（掉线、逃跑），
若仍被Lua需要，则通过pushRequest让Lua知道房间可能已经被释放，否则直接释放。

因为主线程可能处理加入房间的请求，因此整套房间的释放条件判定以及释放必须在主线程执行。

关于释放
~~~~~~~~~~~~~~

释放房内不是人类的玩家。

将旁观者移除房间，若不为人类则释放。

将绑定的RoomThread的引用计数-1。
