简单Elixir游戏服设计-桌子进程跑起来
- 作者: 胡撸小茎肛
- 来源: 51数据库
- 2021-07-01
像Player进程那样增加TableServer代表桌子进程
增加TableSupervisor监控TableServer。使用同一个Registry,因此名字也改成LocalRegistry了。
因此Registry的启动代码,以及原来PlayerServer的register_name要做稍微修改。
当然你也可以使用2个不同的Registry,但恐怕就要增加一个RegstrySupervisor 去start_child了,
又或者手动启动2个(更加不建议)。
新的game_server.ex

defmodule GameServer do
use Application
def start(_type, _args) do
children = [
{Registry, keys: :unique, name: LocalRegistry},
PlayerSupervisor,
TableSupervisor
]
Supervisor.start_link(children, strategy: :one_for_one)
end
end
PlayerServer 的register_name 应该按table_server 那样修改,这样清晰,并且也不会冲突。

defmodule TableServer do
use GenServer, restart: :temporary, start: {__MODULE__, :start_link, []}
def start_link(table) do
GenServer.start_link(__MODULE__, table, name: register_name(table))
end
def init(table) do
{:ok, table}
end
def register_name(%{} = table), do: register_name(table |> SimpleTable.get_id)
def register_name(id), do: {:via, Registry, {LocalRegistry, {Table, id}}}
def exist?(table) do
key = {Table, table |> SimpleTable.get_id}
case Registry.lookup(LocalRegistry, key) do
[{_pid, _}] -> true
[] -> false
end
end
end
新增了exist? 判断函数,以后会有用吧。
原则上当玩家创建了一个牌局后,没解散之前不允许再创建(当然你可以改,我只是简化了)
table_supervisor 测试
defmodule TableSupervisorTest do
use ExUnit.Case
doctest PlayerSupervisor
setup do
Application.stop(GameServer)
Application.start(GameServer)
%{}
end
test "测试TableSupervisor启动TableServer" do
table1 = SimpleTable.init |> SimpleTable.set_id(1)
table2 = SimpleTable.init |> SimpleTable.set_id(2)
assert {:ok, _p1} = TableSupervisor.start_table(table1)
assert {:ok, _p2} = TableSupervisor.start_table(table2)
assert TableServer.exist?(table1)
assert TableServer.exist?(table2)
end
end
改成使用exist? 了
player_supervisor_test.exs 也照着修改。
编译测试ok。
代码变迁参看git吧。
下回我们由玩家创建牌局,一步步展开吧。
XXXX,想了下 上句话不对,创建那些跟玩法也没有关系,先放着,直接起牌局玩才对。
XXXXX,上句好像也不对,本质上server进程只是转调用数据结构的操作,因此牌局玩法完全可以是数据结构的操作先。
所以下回我们直接操作数据,进行牌局。
推荐阅读
