Packages
hangman_text_client
0.1.63
0.1.87
0.1.86
0.1.85
0.1.84
0.1.83
0.1.82
0.1.81
0.1.80
0.1.79
0.1.78
0.1.77
0.1.76
0.1.75
0.1.74
0.1.73
0.1.72
0.1.71
0.1.70
0.1.69
0.1.68
0.1.67
0.1.66
0.1.65
0.1.64
0.1.63
0.1.62
0.1.61
0.1.60
0.1.59
0.1.58
0.1.57
0.1.56
0.1.55
0.1.54
0.1.53
0.1.52
0.1.51
0.1.50
0.1.49
0.1.48
0.1.47
0.1.46
0.1.45
0.1.44
0.1.43
0.1.42
0.1.41
0.1.40
0.1.39
0.1.38
0.1.37
0.1.36
0.1.35
0.1.34
0.1.33
0.1.32
0.1.31
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
Text client for the Hangman Game.
Current section
Files
Jump to
Current section
Files
lib/hangman/text/client/engine.ex
defmodule Hangman.Text.Client.Engine do
@moduledoc """
Starts a game locally or remotely:
- locally when local node is not alive (`:nonode@nohost`)
- remotely on node `:hangman_engine@<hostname>` otherwise
"""
use PersistConfig
alias IO.ANSI.Plus, as: ANSI
alias Hangman.{Engine, Game}
alias Hangman.Text.Client.Message.{
CannotConnectToNode,
ConnectedToNode,
EngineNodeDown,
EngineNotStarted,
GameAlreadyStarted
}
@doc """
Starts locally or remotely a _Hangman Game_ named `game_name`.
"""
@spec new_game(Game.name()) :: Game.name() | no_return
def new_game(game_name), do: node() |> new_game(game_name)
## Private functions
@spec new_game(node, Game.name()) :: Game.name() | no_return
defp new_game(:nonode@nohost = _local_node, game_name) do
{:ok, _apps} = Application.ensure_all_started(:hangman_engine)
{:ok, _pid} = Engine.new_game(game_name)
game_name
end
defp new_game(_local_node, game_name) do
engine_node = engine_node()
if Node.connect(engine_node) do
ConnectedToNode.message(engine_node) |> ANSI.puts()
else
CannotConnectToNode.message(engine_node) |> ANSI.puts()
self() |> Process.exit(:normal)
end
# Synchronizes the global name server with all nodes known to this node.
:ok = :global.sync()
# Remote procedure call to call a function on a remote node.
case :rpc.call(engine_node, Engine, :new_game, [game_name]) do
{:ok, _pid} ->
game_name
{:error, {:already_started, _pid}} ->
GameAlreadyStarted.message(game_name, engine_node) |> ANSI.puts()
self() |> Process.exit(:normal)
{:badrpc, :nodedown} ->
EngineNodeDown.message(engine_node) |> ANSI.puts()
self() |> Process.exit(:normal)
{:badrpc, {:EXIT, {:undef, _}}} ->
EngineNotStarted.message(engine_node) |> ANSI.puts()
self() |> Process.exit(:normal)
error ->
exit(error)
end
end
@spec engine_node :: node
defp engine_node, do: get_env(:engine_node)
end