Packages
hangman_text_client
0.1.49
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
- remotely on node `:hangman_engine@<hostname>` otherwise
"""
use PersistConfig
alias Hangman.{Engine, Game}
@doc """
Starts a game locally or remotely.
"""
@spec new_game(node) :: Game.name() | no_return
def new_game(:nonode@nohost = _local_node) do
{:ok, _apps} = Application.ensure_all_started(:hangman_engine)
game_name = Game.random_name()
{:ok, _pid} = Engine.new_game(game_name)
game_name
end
def new_game(local_node) do
game_name = Atom.to_string(local_node)
engine_node = engine_node()
if Node.connect(engine_node) do
puts(:connected, {engine_node})
else
puts(:cannot_connect, {engine_node})
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}} ->
puts(:game_already_started, {game_name, engine_node})
game_name
{:badrpc, :nodedown} ->
puts(:engine_node_down, {engine_node})
self() |> Process.exit(:normal)
{:badrpc, {:EXIT, {reason, _}}} when reason in [:undef, :noproc] ->
puts(:engine_not_started, {engine_node})
self() |> Process.exit(:normal)
error ->
exit(error)
end
end
## Private functions
@spec engine_node :: node
defp engine_node, do: get_env(:engine_node)
@spec puts(atom, tuple) :: :ok
defp puts(:cannot_connect, {node}) do
IO.puts("Cannot connect to node #{inspect(node)}.")
end
defp puts(:connected, {node}) do
IO.puts("Connected to node #{inspect(node)}...")
end
defp puts(:game_already_started, {name, node}) do
{name, node} = {inspect(name), inspect(node)}
IO.puts("Hangman Game #{name} already started on node #{node}.")
end
defp puts(:engine_node_down, {node}) do
IO.puts("Hangman Engine node #{inspect(node)} is down.")
end
defp puts(:engine_not_started, {node}) do
IO.puts("Hangman Engine not started on node #{inspect(node)}.")
end
end