日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Erlang/OTP之gen_fsm行为模式

發布時間:2025/4/5 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Erlang/OTP之gen_fsm行为模式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

 1. Fsm 稱為 有限狀態機,舉個例子,游戲中的怪物稱為NPC,NPC一般有幾種狀態,比如:靜止,移動,死亡,被攻擊,攻擊英雄等等幾個有限的狀態,那么我們就可以有限狀態機實現NPC的狀態變更。


  一個有限狀態機可以用一個關系式來描述,State(靜止狀態S1) x Event(英雄進入視野范圍事件E) -> Actions(開始移動動作A), State(移動狀態S2)


  解釋如下:當一個NPC處于靜止狀態S1,有一個英雄進入NPC視野范圍時E,會觸發NPC開始移動動作A,并且NPC轉變狀態為移動狀態S2。


  對于一個用 gen_fsm 行為實現的FSM來說,狀態轉換規則被寫為符合如下約定的一系列Erlang函數:


StateName( Event, StateData ) ->


    .. 這里放動作的代碼 ...


    { next_state, StateName', StateData' }

  2. 接下來我們來看個例子,游戲中NPC狀態變化,當然我做了很大的簡化,真正游戲中的邏輯比這復雜的多。這里我只是為了說明,erlang OTP設計原則中的gen_fsm如何使用,代碼如下:


-module(npc).

?

-behaviour(gen_fsm).

?

%% API

-export([start_link/0]).

?

%% gen_fsm callbacks

-export([init/1, static/2, moving/2, handle_event/3,

? ? ?handle_sync_event/4, handle_info/3, terminate/3, code_change/4]).

?

-export([hero_join/0, hero_leave/0]).

?

-define(SERVER, ?MODULE).

?

-record(npc, {state}).

?

start_link() ->

? ? gen_fsm:start_link({local, ?SERVER}, ?MODULE, [], []).

?

%% 初始化NPC為靜止狀態

init([]) ->

? ? io:format("init...~n"),

? ? State = #npc{state = static},

? ? io:format("init State: ~p~n", [State]),

   {ok, static, State}.

?

%% 英雄進入視野

hero_join() ->

? ? gen_fsm:send_event(?SERVER, hero_join).

?

%% 英雄離開視野

hero_leave() ->

? ? gen_fsm:send_event(?SERVER, hero_leave).

?

%% 靜止狀態下,接受來自客戶端的事件

static(Event, State) ->

? ? case Event of

? ? hero_join -> %% 英雄進入視野

? ? ? ? do_moving(), %% 執行動作

? ? ? ? NewState = State#npc{state = moving},

? ? ? ? io:format("npc set state: ~p~n", [NewState]),

? ? ? ? {next_state, moving, NewState}

? ? end.

?

%% 移動狀態下,接受來自客戶端的事件

moving(Event, State) ->

? ? case Event of

? ? hero_leave -> %% 英雄離開視野

? ? ? ? do_static(), %% 執行動作

? ? ? ? NewState = State#npc{state = static},

? ? ? ? io:format("npc set state: ~p~n", [NewState]),

? ? ? ? {next_state, static, NewState}

? ? end.

?

handle_event(_Event, StateName, State) ->

? ? {next_state, StateName, State}.

?

handle_sync_event(_Event, _From, StateName, State) ->

? ? Reply = ok,

? ? {reply, Reply, StateName, State}.

?

handle_info(_Info, StateName, State) ->

? ? {next_state, StateName, State}.

?

terminate(_Reason, _StateName, _State) ->

? ? ok.

?

code_change(_OldVsn, StateName, State, _Extra) ->

? ? {ok, StateName, State}.

?

%% NPC 開始移動,進入移動狀態

do_moving() ->

? ? io:format("npc beigin moving...~n").

?

%% NPC 停止移動,進入靜止狀態

do_static() ->

? ? io:format("npc stop moving, join static...~n").

?  代碼注釋比較詳細,接下來可以通過運行代碼,來好好理解下這個例子,


  1. 首先,調用 npc:start_link(). 來初始化NPC服務;這個時候NPC處于靜止狀態 static;


  2. 當npc處于靜止狀態時,我們通過調用 npc:hero_join().來表示有一個俠客進入NPC的視野,那么這個時候gen_fsm會默認調用當前gen_fsm處于的狀態,也就是static的處理方法,也就是 static(Event, State) 這個函數,這邊可能比較繞,我已經盡量去用直白的語言來表達,能力有限,大家多思考下,呵呵;


  3. 當處理 static 函數時,Event 這個變量,就是 gen_fsm:send_event(?SERVER, hero_join). hero_join,緊接著執行對應的動作,在這里也就是 do_moving(),開始移動;


  4. 最后,我們需要返回 {next_state, moving, NewState} 讓gen_fsm進入下一個狀態,也就是 moving 狀態;


  5. 當npc處于移動時,我們通過調用 npc:hero_leave(). 來表示 該俠客移動NPC的視野,那么對應的 moving(Event, State) 函數就會被調用,其他的處理與 static 時的處理是類似的,這里就不重復表述了。


轉載于:https://my.oschina.net/u/1540325/blog/370105

總結

以上是生活随笔為你收集整理的Erlang/OTP之gen_fsm行为模式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。