Some changes to how games are created
Some checks failed
Build & Test / nix-build (push) Failing after 27s
Some checks failed
Build & Test / nix-build (push) Failing after 27s
This commit is contained in:
parent
ec7119251c
commit
dc9a2f2b5f
@ -27,7 +27,11 @@ defmodule Amethyst.Application do
|
|||||||
{Task.Supervisor, name: Amethyst.ConnectionSupervisor},
|
{Task.Supervisor, name: Amethyst.ConnectionSupervisor},
|
||||||
{Amethyst.Keys, 1024},
|
{Amethyst.Keys, 1024},
|
||||||
{Amethyst.GameRegistry, []},
|
{Amethyst.GameRegistry, []},
|
||||||
{Amethyst.GameCoordinator, []}
|
{Amethyst.GameCoordinator, []},
|
||||||
|
{PartitionSupervisor,
|
||||||
|
child_spec: DynamicSupervisor.child_spec([]),
|
||||||
|
name: Amethyst.GameMetaSupervisor
|
||||||
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
children = case Application.fetch_env!(:amethyst, :port) do
|
children = case Application.fetch_env!(:amethyst, :port) do
|
||||||
|
@ -19,9 +19,9 @@ defmodule Amethyst.API.Game do
|
|||||||
This module includes the interface for defining and registering
|
This module includes the interface for defining and registering
|
||||||
a game with Amethyst.
|
a game with Amethyst.
|
||||||
"""
|
"""
|
||||||
@callback instantiate() :: {:ok, new_state :: term} | {:error, reason :: term}
|
@callback instantiate(supervisor :: pid()) :: {:ok, state_refs :: map()} | {:error, reason :: term}
|
||||||
@callback login(from :: pid(), player_cfg :: keyword(), state :: term) :: {:ok, new_state :: term} | {:refuse, new_state :: term}
|
@callback login(from :: pid(), player_cfg :: keyword(), state_refs :: map()) :: :ok
|
||||||
@callback player_position(from :: pid(), {x :: float(), y :: float(), z :: float()}, state :: term) :: {{x :: float(), y :: float(), z :: float()}, state :: term}
|
@callback player_position(from :: pid(), {x :: float(), y :: float(), z :: float()}, state_refs :: map()) :: :ok
|
||||||
|
|
||||||
defmacro __using__(opts) do
|
defmacro __using__(opts) do
|
||||||
meta = Keyword.get(opts, :meta, [])
|
meta = Keyword.get(opts, :meta, [])
|
||||||
@ -41,27 +41,20 @@ defmodule Amethyst.API.Game do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@spec start(Amethyst.API.Game, term()) :: no_return()
|
@spec start(Amethyst.API.Game, term()) :: no_return()
|
||||||
def start(mod, state) do
|
def start(mod, refs) do
|
||||||
loop(mod, state)
|
true = refs |> Enum.all?(fn {_key, pid } -> Process.link(pid) end)
|
||||||
|
loop(mod, refs)
|
||||||
end
|
end
|
||||||
defp loop(mod, state) do
|
defp loop(mod, refs) do
|
||||||
receive do
|
receive do
|
||||||
{:login, caller, cfg} ->
|
{:login, caller, cfg} ->
|
||||||
case mod.login(caller, cfg, state) do
|
Task.Supervisor.start_child(refs[:task_supervisor],
|
||||||
{:ok, state} ->
|
fn -> mod.login(caller, cfg, refs) end)
|
||||||
send(caller, :ok)
|
|
||||||
loop(mod, state)
|
|
||||||
{:refuse, state} ->
|
|
||||||
send(caller, :refuse)
|
|
||||||
loop(mod, state)
|
|
||||||
end
|
|
||||||
{:player_position, caller, pos} ->
|
{:player_position, caller, pos} ->
|
||||||
case mod.player_position(caller, pos, state) do
|
Task.Supervisor.start_child(refs[:task_supervisor],
|
||||||
{pos, state} ->
|
fn -> mod.player_position(caller, pos, refs) end)
|
||||||
send(caller, pos)
|
|
||||||
loop(mod, state)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
loop(mod, refs)
|
||||||
end
|
end
|
||||||
|
|
||||||
def login(pid, cfg) do
|
def login(pid, cfg) do
|
||||||
|
@ -53,8 +53,20 @@ defmodule Amethyst.GameCoordinator do
|
|||||||
end
|
end
|
||||||
|
|
||||||
defp _create(type, games) do
|
defp _create(type, games) do
|
||||||
state = type.instantiate()
|
# Create a DynamicSupervisor for this game
|
||||||
pid = spawn(Amethyst.API.Game, :start, [type, state])
|
{:ok, game_supervisor_pid} = DynamicSupervisor.start_child(
|
||||||
|
{:via, PartitionSupervisor, {Amethyst.GameMetaSupervisor, type}},
|
||||||
|
DynamicSupervisor
|
||||||
|
)
|
||||||
|
{:ok, task_supervisor_pid} = DynamicSupervisor.start_child(
|
||||||
|
game_supervisor_pid,
|
||||||
|
Task.Supervisor
|
||||||
|
)
|
||||||
|
# TODO: Instantiation can fail (including with an exception), and if it does the entire GameCoordinator goes down
|
||||||
|
# We should gracefully handle situations where we cannot create a game.
|
||||||
|
{:ok, refs} = type.instantiate(game_supervisor_pid)
|
||||||
|
refs = refs |> Map.put(:game_supervisor, game_supervisor_pid) |> Map.put(:task_supervisor, task_supervisor_pid)
|
||||||
|
pid = spawn(Amethyst.API.Game, :start, [type, refs])
|
||||||
games = [{type, pid, []} | games]
|
games = [{type, pid, []} | games]
|
||||||
{pid, games}
|
{pid, games}
|
||||||
end
|
end
|
||||||
|
@ -3,13 +3,14 @@ defmodule Example.Game do
|
|||||||
use Amethyst.API.Game, meta: [default: true]
|
use Amethyst.API.Game, meta: [default: true]
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def instantiate() do
|
def instantiate(supervisor) do
|
||||||
{:ok, [:hello]}
|
Logger.info("The supervisor for this game is at #{inspect(supervisor)}")
|
||||||
|
{:ok, %{}}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def login(from, cfg, state) do
|
def login(from, cfg, _state) do
|
||||||
Logger.info("Player logged in from #{inspect(from)}: #{inspect(cfg)}")
|
Logger.info("Player logged in from #{inspect(from)}: #{inspect(cfg)}")
|
||||||
{:ok, state}
|
:ok
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user