• 简单Elixir游戏服设计- 丰富桌子进程


    轮到处理桌子进程了。桌子进程抛开消息发送,基本上就是table的转调用。

    无谓测试驱动先还是写代码先,反正怎么顺就怎么搞。

    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
    
        def create(player) do
            table = SimpleTable.init 
                    |> SimpleTable.set_id(player |> Player.get_id)
                    |> SimpleTable.set_creator(player)
                    |> SimpleTable.add_seat(player)
            TableSupervisor.start_table(table)
        end
    
        def join(table, player), do: GenServer.cast(table, {:join, player: player})
    
        def quit(table, player), do: GenServer.cast(table, {:quit, player: player})
    
        def dismiss(table, player), do: GenServer.cast(table, {:dismiss, player: player})
    
        def start(table, player), do: GenServer.cast(table, {:start, player: player})
    
        def open(table, player), do: GenServer.cast(table, {:open, player: player})
    
        def makeup(table, player), do: GenServer.cast(table, {:makeup, player: player})
    
        def handle_cast(request, table) do
            {:ok, table} = inner_handle_cast(request, table) 
            {:noreply, table}
        end
    
    
    
        def send_error(_player, _error) do
        
        end
    
      
    
        def inner_handle_cast({:join, player: player}, table) do 
            with {:ok, table}  <- table |> SimpleTable.join(player)
            do
                seat = SimpleTable.find_seat(table, player)
                broadcast_join(table, seat)
            else
                {:error, error} ->
                    send_error(player, error)
            end
            {:ok, table}
        end
    
        def inner_handle_cast({:quit, player: player}, table) do
            with {:ok, table} <- table |> SimpleTable.quit(player)
            do
                broadcast_quit(table, player)
            else
                {:error, error} ->
                    send_error(player, error)
            end
            {:ok, table}
           end
    
        def inner_handle_cast({:dismiss, player: player}, table) do
            with {:ok, table} <- table |> SimpleTable.dismiss(player)
            do
                broadcast_dismiss(table)
            else
                {:error, error} ->
                    send_error(player, error)
            end
            {:ok, table}
        end
    
        def inner_handle_cast({:start, player: player}, table) do
            with {:ok, table} <-    table |> SimpleTable.start(player)
            do
                broadcast_start(table)
            else
                {:error, error} ->
                    send_error(player, error)
            end
            {:ok, table}
        end
    
        def inner_handle_cast({:open, player: player}, table) do
            with {:ok, table} <- table |> SimpleTable.open(player)
            do
                send_open(table, player)
            else
                {:error, error} ->
                    send_error(player, error)
            end
            {:ok, table}
        end
    
        def inner_handle_cast({:makeup, player: player}, table) do
            with {:ok, table} <- table |> SimpleTable.make_up(player)
            do
                send_makeup(table, player)
            else
                {:error, error} ->
                    send_error(player, error)
            end
            {:ok, table}
        end
    
        def broadcast_join(_table, _seat) do
            
        end
    
        def broadcast_quit(_table, _player) do
            
        end
    
        def broadcast_dismiss(_table) do
            
        end
    
        def broadcast_start(_table) do
            
        end
    
        def send_open(_table, _player) do
            
        end
    
        def send_makeup(_table, _player) do
            
        end
    
    end
    table_server.ex

    虽然table_server 很简单,但我还是花了点时间在上面。

    主要在考虑下面的问题:

    1. 要不要用exactor 库简化api接口

      后来没有用, exactor 还是适合于速错模式用, 而游戏我们通常要try catch,如果要用,需要包装exactor的宏,麻烦。

           当然如果把table存到ets里, 就可以比较方便的崩溃恢复, 也许这比较适合用exactor。

    2. inner_handle_cast  应该是怎么样的接口才方便修改

          想来想去,用  {cmd, keyword_list} 比较方便, 直观且容易修改

    3. 消息发送怎么样才方便以及直观

      一开始是尝试 broadcast_table, 诱惑是凡是发消息就调用该接口。

          但明显感觉有2个缺陷

          一个是粒度太大(结果是该函数里比如要有不同分支)

          一个无法直观每个操作的具体影响

         所以最后改成,需要发送什么,就搞个api发送什么, 这就有broadcast_join broadcast_quit 等等,

        感觉就清晰很多,自然很多,并且粒度小了发送的信息也少了。

    下回增加相关的测试和代码吧

  • 相关阅读:
    【LeetCode】Rotate List
    【LeetCode】Longest Valid Parentheses
    【LeetCode】Longest Substring Without Repeating Characters
    【LeetCode】Multiply Strings
    【LeetCode】Triangle
    hdfs 查看报告--命令(hdfs dfsadmin -report)
    hive
    java ---面向对象
    java--数组
    java--函数
  • 原文地址:https://www.cnblogs.com/rubyist/p/7677049.html
Copyright © 2020-2023  润新知