Skip to content

Instantly share code, notes, and snippets.

@leikind
Created Dec 13, 2011
Embed
What would you like to do?
-module(dog_fsm).
-behaviour (gen_fsm).
% gen_fsm behavior implementation
-export([ init/1, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]).
% states
-export([ barks/2, wag_tail/2, sit/2]).
% test
-export([ test/0]).
%% client stuff
squirrel(Pid) ->
gen_fsm:send_event(Pid, squirrel).
pet(Pid) ->
gen_fsm:send_event(Pid, pet).
%% gen_fsm chrome
init(_State) ->
Timer = set_timer_to_transition_from_state_to_itself_on_a_timeout(2000),
{ok, barks, [Timer]}.
terminate(Reason, StateName, _StateData) ->
io:format("terminating with reason ~p at state ~p~n",[Reason, StateName]),
ok.
code_change(_OldVsn, StateName, Data, _Extra) ->
{ok, StateName, Data}.
handle_info(Info, StateName, Data) ->
io:format("~p received unknown event ~p while in state ~p~n", [self(), Info, StateName]),
{next_state, StateName, Data}.
%% State Transitions
barks(pet, StateData) ->
cancel_all_timers(StateData),
io:format("Dog wags its tail~n"),
Timer = set_timer_to_transition_from_state_to_itself_on_a_timeout(30000),
{next_state, wag_tail, [Timer]};
%% Transition to itself
barks(timeout, _StateData) ->
Timer = set_timer_to_transition_from_state_to_itself_on_a_timeout(2000),
io:format("Dog says: BARK! BARK!~n"),
{next_state, barks, [Timer]};
barks(Event, StateData) ->
unexpected_event(barks, Event, StateData),
{next_state, barks, StateData}.
wag_tail(pet, StateData) ->
cancel_all_timers(StateData),
io:format("Dog is sitting. Gooooood boy!~n"),
{next_state, sit, []};
wag_tail(timeout, _StateData) ->
Timer = set_timer_to_transition_from_state_to_itself_on_a_timeout(2000),
{next_state, barks, [Timer]};
wag_tail(Event, StateData) ->
unexpected_event(wag_tail, Event, StateData),
{next_state, wag_tail, StateData}.
sit(squirrel, _StateData) ->
Timer = set_timer_to_transition_from_state_to_itself_on_a_timeout(2000),
io:format("Dog says: BARK! BARK!~n"),
{next_state, barks, [Timer]};
sit(Event, StateData) ->
unexpected_event(sit, Event, StateData),
{next_state, sit, StateData}.
handle_event(shutdown, _StateName, State) ->
{stop, normal, State};
handle_event(Event, StateName, State) ->
io:format("Dog receives an unknown global event: ~p ~n", [Event]),
{next_state, StateName, State}.
handle_sync_event(Event, _From, StateName, _State) ->
io:format("Dog receives an unknown global sync event: ~p ~n", [Event]),
{reply, "You are not understood", Event, StateName}.
%% private
unexpected_event(_CurrentState, _Event, _StateData) ->
io:format("Dog is confused~n").
set_timer_to_transition_from_state_to_itself_on_a_timeout(Timeout) ->
gen_fsm:send_event_after(Timeout, timeout).
cancel_all_timers(Timers) -> lists:map(
fun(Timer) ->
gen_fsm:cancel_timer(Timer)
end,
Timers).
%% test
test() ->
spawn(fun() ->
{ok, Pid} = gen_fsm:start_link(?MODULE, [], []),
timer:sleep(6000),
pet(Pid),
pet(Pid),
pet(Pid),
squirrel(Pid),
timer:sleep(6000),
pet(Pid),
timer:sleep(35000),
pet(Pid),
pet(Pid),
gen_fsm:send_all_state_event(Pid, shutdown)
end).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment