Created
December 13, 2011 00:10
-
-
Save leikind/1469767 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-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