Current section

Files

Jump to
erlang_behaviour_trees src samples processes dummy_navigator.erl
Raw

src/samples/processes/dummy_navigator.erl

-module(dummy_navigator).
-behaviour(gen_server).
-export([
%% api
start_link/2,
goto_barcode/2,
teleport_butler/2,
lift/2,
get_location/1,
get_lift_state/1,
%% cb
init/1,
handle_call/3,
handle_cast/2
]).
-record(state, {
butler_id,
current_location,
lift_state = down,
going_to_barcode,
count
}).
%% api
start_link(BId, Location) ->
gen_server:start_link(?MODULE, [BId, Location], []).
goto_barcode(Pid, Barcode) ->
gen_server:cast(Pid, {goto_barcode, Barcode}).
%% teleportation for testing
teleport_butler(Pid, Barcode) ->
gen_server:cast(Pid, {teleport, Barcode}).
lift(Pid, Direction) ->
gen_server:cast(Pid, {lift, Direction}).
get_location(Pid) ->
gen_server:call(Pid, get_location).
get_lift_state(Pid) ->
gen_server:call(Pid, get_lift_state).
%% cb
init([BId, Location]) ->
gproc:add_local_name({?MODULE, BId}),
{ok, #state{
butler_id = BId,
current_location = Location,
lift_state = down,
count = 0
}}.
handle_call(get_location, _From, State) ->
{reply, State#state.current_location, State};
handle_call(get_lift_state, _From, State) ->
{reply, State#state.lift_state, State}.
handle_cast({goto_barcode, Barcode}, State = #state{butler_id = BId, current_location = PrevLocation, lift_state = LiftState}) ->
{noreply, NewState = #state{current_location = NewLocation}} = handle_goto_barcode({goto_barcode, Barcode}, State),
%% broadcast this
gproc:send({p, l, {pubsub, on_butler_move}},
{self(), {pubsub, on_butler_move}, {BId, PrevLocation, NewLocation, LiftState}}),
{noreply, NewState};
handle_cast({teleport, Barcode}, State) ->
{noreply, State#state{count = 0, current_location = Barcode, going_to_barcode = undefined}};
handle_cast({lift, up}, State) ->
{noreply, State#state{lift_state = up}};
handle_cast({lift, down}, State) ->
{noreply, State#state{lift_state = down}}.
%% if already at this barcode, just reset counters and do nothing
handle_goto_barcode({goto_barcode, CurrentBarcode}, State = #state{current_location = CurrentBarcode}) ->
{noreply, State};
%% after 5 counts of requests of going to same barcode, just go to it
handle_goto_barcode({goto_barcode, GoingToBarcode}, State = #state{count = 5, going_to_barcode = GoingToBarcode}) ->
{noreply, State#state{current_location = GoingToBarcode, going_to_barcode = undefined, count = 0}};
%% if its same as going_to_barcode but count is not 5 yet, then move butler to some random barcode and increase count
handle_goto_barcode({goto_barcode, GoingToBarcode}, State = #state{count = Count, going_to_barcode = GoingToBarcode}) ->
{noreply, State#state{count = Count + 1, current_location = butler_functions:gen_random_barcode()}};
%% if its not current barcode or going to barcode, reset counter and make it the going to barcode. also randomly move butler somewhere
handle_goto_barcode({goto_barcode, Barcode}, State = #state{going_to_barcode = GoingToBarcode}) when Barcode =/= GoingToBarcode ->
{noreply, State#state{count = 0, current_location = butler_functions:gen_random_barcode(), going_to_barcode = Barcode}}.