Skip to content

Commit

Permalink
Add GameRegistry: GameUIServer spawn/die controls Room rows
Browse files Browse the repository at this point in the history
- Create a GameUIServer: Room automatically created
- GameUIServer dies to timeout: Room deleted, GameServer deleted
- API to create rooms directly removed
  • Loading branch information
mreishus committed Oct 25, 2019
1 parent 9db839f commit 676d6f7
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 71 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*.swp
*.swo
priv_notes.txt
1 change: 1 addition & 0 deletions backend/.iex.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
alias Spades.Rooms
alias Spades.Rooms.Room

alias SpadesGame.{
Card,
Expand Down
5 changes: 5 additions & 0 deletions backend/lib/spades/rooms.ex
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ defmodule Spades.Rooms do
"""
def get_room!(id), do: Repo.get!(Room, id)

def get_room_by_name(name) do
Room
|> Repo.get_by(name: name)
end

@doc """
Creates a room.
Expand Down
1 change: 1 addition & 0 deletions backend/lib/spades_game/game_options.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ defmodule SpadesGame.GameOptions do
hardcoded_cards: boolean
}

@derive {Jason.Encoder, only: [:hardcoded_cards]}
schema "gameuioptions" do
field(:hardcoded_cards, :boolean)
end
Expand Down
40 changes: 40 additions & 0 deletions backend/lib/spades_game/game_registry.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule SpadesGame.GameRegistry do
@moduledoc """
Keeps track of games.
"""
require Logger
alias SpadesGame.{GameUI}
alias Spades.Rooms
alias Spades.Rooms.Room

def add(_game_name, %GameUI{} = gameui) do
gameui
|> to_room_param()
|> Rooms.create_room()
end

def update(game_name, %GameUI{} = gameui) do
room = Rooms.get_room_by_name(game_name)

case room do
%Room{} -> Rooms.update_room(room, to_room_param(gameui))
_ -> nil
end
end

def remove(game_name) do
room = Rooms.get_room_by_name(game_name)

case room do
%Room{} -> Rooms.delete_room(room)
_ -> nil
end
end

defp to_room_param(%GameUI{} = gameui) do
# created_at: DateTime.t()
%{
name: gameui.game_name
}
end
end
13 changes: 8 additions & 5 deletions backend/lib/spades_game/ui/game_ui_server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule SpadesGame.GameUIServer do
@timeout :timer.hours(1)

require Logger
alias SpadesGame.{GameOptions, GameUI}
alias SpadesGame.{GameOptions, GameUI, GameRegistry, GameSupervisor}

@doc """
start_link/2: Generates a new game server under a provided name.
Expand Down Expand Up @@ -49,7 +49,7 @@ defmodule SpadesGame.GameUIServer do

def init({game_name, options = %GameOptions{}}) do
gameui = GameUI.new(game_name, options)
# GameRegistry.add(gameui.game_name, game_info(gameui))
GameRegistry.add(gameui.game_name, gameui)
{:ok, gameui, timeout(gameui)}
end

Expand All @@ -59,6 +59,9 @@ defmodule SpadesGame.GameUIServer do
{:reply, new_state, new_state, timeout(new_state)}
end

# In some state updating function:
# GameRegistry.update(new_gameui.game_name, gameui)

# timeout/1
# Given the current state of the game, what should the
# GenServer timeout be? (Games with winners expire quickly)
Expand All @@ -73,15 +76,15 @@ defmodule SpadesGame.GameUIServer do

def terminate({:shutdown, :timeout}, state) do
Logger.info("Terminate (Timeout) running for #{state.game_name}")
# GameSupervisor.stop_game(state.game_name)
# GameRegistry.remove(state.game_name)
GameSupervisor.stop_game(state.game_name)
GameRegistry.remove(state.game_name)
:ok
end

# Do I need to trap exits here?
def terminate(_reason, state) do
Logger.info("Terminate (Non Timeout) running for #{state.game_name}")
# GameRegistry.remove(state.game_name)
GameRegistry.remove(state.game_name)
:ok
end
end
27 changes: 27 additions & 0 deletions backend/lib/spades_web/controllers/api/v1/game_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule SpadesWeb.API.V1.GameController do
use SpadesWeb, :controller

require Logger

alias Spades.Rooms
alias Spades.Rooms.Room
alias SpadesUtil.{NameGenerator}
alias SpadesGame.{GameOptions, GameUISupervisor}

def create(conn, _params) do
game_name = NameGenerator.generate()
options = %GameOptions{}

with {:ok, _pid} <- GameUISupervisor.start_game(game_name, options),
%Room{} = room <- Rooms.get_room_by_name(game_name) do
conn
|> put_status(:created)
|> json(%{success: %{message: "Created game", room: room}})
else
_ ->
conn
|> put_status(500)
|> json(%{error: %{status: 500, message: "Unable to create game"}})
end
end
end
22 changes: 4 additions & 18 deletions backend/lib/spades_web/controllers/room_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ defmodule SpadesWeb.RoomController do

alias Spades.Rooms
alias Spades.Rooms.Room
alias SpadesUtil.{NameGenerator, Slugify}
alias SpadesGame.GameSupervisor
# alias SpadesUtil.{NameGenerator, Slugify}
# alias SpadesGame.GameSupervisor

action_fallback SpadesWeb.FallbackController

Expand All @@ -13,22 +13,8 @@ defmodule SpadesWeb.RoomController do
render(conn, "index.json", rooms: rooms)
end

def create(conn, %{"room" => room_params}) do
game_name = NameGenerator.generate()

room_params =
room_params
|> Map.put("name", game_name)
|> Map.put("slug", Slugify.slugify(game_name))

with {:ok, _pid} <- GameSupervisor.start_game(game_name),
{:ok, %Room{} = room} <- Rooms.create_room(room_params) do
conn
|> put_status(:created)
|> put_resp_header("location", Routes.room_path(conn, :show, room))
|> render("show.json", room: room)
end
end
# Create: Removed, users no longer able to create rooms by API
# Possibly this entire controller should be removed

def show(conn, %{"id" => id}) do
room = Rooms.get_room!(id)
Expand Down
1 change: 1 addition & 0 deletions backend/lib/spades_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ defmodule SpadesWeb.Router do

# Testing Junk
get "/authtest", JunkController, :authtest
post "/games", GameController, :create
end

scope "/api/v1", SpadesWeb.API.V1, as: :api_v1 do
Expand Down
3 changes: 2 additions & 1 deletion backend/test/spades_game/ui/game_ui_server_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule GameUiServerTest do
use ExUnit.Case, async: true
use ExUnit.Case
use Spades.DataCase
alias SpadesGame.{Card, GameOptions, GameUIServer, GameUI, Game}

describe "start_link/2" do
Expand Down
3 changes: 2 additions & 1 deletion backend/test/spades_game/ui/game_ui_supervisor_test.exs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule GameUiSupervisorTest do
use ExUnit.Case, async: true
use ExUnit.Case
use Spades.DataCase
doctest SpadesGame.GameUISupervisor

alias SpadesGame.{GameUISupervisor, GameUIServer, GameOptions}
Expand Down
33 changes: 0 additions & 33 deletions backend/test/spades_web/controllers/room_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,39 +28,6 @@ defmodule SpadesWeb.RoomControllerTest do
end
end

describe "create room" do
test "renders room when data is valid", %{conn: conn} do
#############
# a = Routes.room_path(conn, :create)
# a |> IO.inspect(label: "path")

# @create_attrs
# |> IO.inspect(label: "attrs")

#############

conn = post(conn, Routes.room_path(conn, :create), room: @create_attrs)
assert %{"id" => id} = json_response(conn, 201)["data"]

conn = get(conn, Routes.room_path(conn, :show, id))

assert %{
"id" => id
# "name" => "some name"
# Name is automatically generated.
} = json_response(conn, 200)["data"]
end

## Since names are automatically generated, and
## they're the only field right now, we can't
## generate invalid data.

# test "renders errors when data is invalid", %{conn: conn} do
# conn = post(conn, Routes.room_path(conn, :create), room: @invalid_attrs)
# assert json_response(conn, 422)["errors"] != %{}
# end
end

describe "update room" do
setup [:create_room]

Expand Down
10 changes: 3 additions & 7 deletions frontend/src/features/lobby/CreateRoomModal.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import React, { useState } from "react";
import { Redirect } from "react-router";
import axios from "axios";
//import cx from "classnames";
import ReactModal from "react-modal";
import Button from "../../components/basic/Button";

import { getRandomInt } from "../../util/util";

interface Props {
isOpen: boolean;
closeModal: () => void;
Expand All @@ -20,17 +17,16 @@ export const CreateRoomModal: React.FC<Props> = ({ isOpen, closeModal }) => {
const [roomSlugCreated, setRoomSlugCreated] = useState(null);

const createRoom = async () => {
const name = "Room Name " + getRandomInt(1, 10000);
const data = { room: { name } };
const data = { room: { name: "" } };
setIsLoading(true);
setIsError(false);
try {
const res = await axios.post("/be/api/rooms", data);
const res = await axios.post("/be/api/v1/games", data);
setIsLoading(false);
if (res.status !== 201) {
throw new Error("Room not created");
}
const room = res.data.data;
const room = res.data.success.room;
setRoomSlugCreated(room.slug);
} catch (err) {
setIsLoading(false);
Expand Down
14 changes: 8 additions & 6 deletions frontend/src/features/lobby/Lobby.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,14 @@ export const Lobby: React.FC = () => {
{roomItems && (
<table className="shadow rounded border bg-gray-100">
<thead>
<th className={thClass}>id</th>
<th className={thClass}>name</th>
<th className={thClass}>west</th>
<th className={thClass}>north</th>
<th className={thClass}>east</th>
<th className={thClass}>south</th>
<tr>
<th className={thClass}>id</th>
<th className={thClass}>name</th>
<th className={thClass}>west</th>
<th className={thClass}>north</th>
<th className={thClass}>east</th>
<th className={thClass}>south</th>
</tr>
</thead>
<tbody>{roomItems}</tbody>
</table>
Expand Down

0 comments on commit 676d6f7

Please sign in to comment.