init: inital commit
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
defmodule Localiser.Localisation.Room.Server do
|
||||
use GenServer
|
||||
|
||||
@pubsub Localiser.PubSub
|
||||
|
||||
defstruct [:id, :name, :offset_x, :offset_y, :width, :height, occupants: MapSet.new()]
|
||||
|
||||
def start_link(room) do
|
||||
GenServer.start_link(__MODULE__, room, name: via(room.id))
|
||||
end
|
||||
|
||||
def via(room_id) do
|
||||
{:via, Registry, {Localiser.Registry, {:room, room_id}}}
|
||||
end
|
||||
|
||||
def tag_entered(room_id, tag_id) do
|
||||
GenServer.cast(via(room_id), {:tag_entered, tag_id})
|
||||
end
|
||||
|
||||
def tag_left(room_id, tag_id) do
|
||||
GenServer.cast(via(room_id), {:tag_left, tag_id})
|
||||
end
|
||||
|
||||
def get_occupants(room_id) do
|
||||
GenServer.call(via(room_id), :get_occupants)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(room) do
|
||||
state = %__MODULE__{
|
||||
id: room.id,
|
||||
name: room.name,
|
||||
offset_x: room.offset_x || 0.0,
|
||||
offset_y: room.offset_y || 0.0,
|
||||
width: room.width || 0.0,
|
||||
height: room.height || 0.0
|
||||
}
|
||||
|
||||
{:ok, state}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_cast({:tag_entered, tag_id}, state) do
|
||||
new_occupants = MapSet.put(state.occupants, tag_id)
|
||||
|
||||
if new_occupants != state.occupants do
|
||||
broadcast(state.id, new_occupants)
|
||||
end
|
||||
|
||||
{:noreply, %{state | occupants: new_occupants}}
|
||||
end
|
||||
|
||||
def handle_cast({:tag_left, tag_id}, state) do
|
||||
new_occupants = MapSet.delete(state.occupants, tag_id)
|
||||
|
||||
if new_occupants != state.occupants do
|
||||
broadcast(state.id, new_occupants)
|
||||
end
|
||||
|
||||
{:noreply, %{state | occupants: new_occupants}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_call(:get_occupants, _from, state) do
|
||||
{:reply, state.occupants, state}
|
||||
end
|
||||
|
||||
defp broadcast(room_id, occupants) do
|
||||
Phoenix.PubSub.broadcast(
|
||||
@pubsub,
|
||||
"room:#{room_id}",
|
||||
{:room_occupancy_changed, room_id, occupants}
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,41 @@
|
||||
defmodule Localiser.Localisation.Room.Supervisor do
|
||||
use DynamicSupervisor
|
||||
|
||||
alias Localiser.Domain.Rooms
|
||||
alias Localiser.Localisation.Room.Server
|
||||
|
||||
def start_link(floor) do
|
||||
case DynamicSupervisor.start_link(__MODULE__, :ok, name: via(floor.id)) do
|
||||
{:ok, pid} ->
|
||||
seed_rooms(floor.id)
|
||||
{:ok, pid}
|
||||
|
||||
error ->
|
||||
error
|
||||
end
|
||||
end
|
||||
|
||||
def via(floor_id) do
|
||||
{:via, Registry, {Localiser.Registry, {:room_supervisor, floor_id}}}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init(:ok) do
|
||||
DynamicSupervisor.init(strategy: :one_for_one)
|
||||
end
|
||||
|
||||
def start_room_server(floor_id, room) do
|
||||
child_spec = %{
|
||||
id: {Server, room.id},
|
||||
start: {Server, :start_link, [room]},
|
||||
restart: :transient
|
||||
}
|
||||
|
||||
DynamicSupervisor.start_child(via(floor_id), child_spec)
|
||||
end
|
||||
|
||||
defp seed_rooms(floor_id) do
|
||||
Rooms.list_rooms_for_floor(floor_id)
|
||||
|> Enum.each(&start_room_server(floor_id, &1))
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user