您的位置:首页 > 其它

Erlang入门:服务进程实例操作与练习3

2015-01-13 12:39 363 查看
银行服务使用示例:

创建用户:bank_server:create_account(myname, 100).

用户存钱:myname ! {deposit, 10}.

用户取钱:myname ! {cash1, 20}.

myname ! {cash2, 30}.

查询余额:myname ! check.

========================

游戏角色使用示例:

创建角色:{ok, Pid} = game_server:create_player(Id, Hp, Mp).

角色加血:Pid ! {add_hp, 100}.

角色加魔:Pid ! {add_mp, 100}.

查看角色:Pid ! show.

%% @author Rolong
%%
%% server module            Callback module
%% -----------------        ---------------
%%
%% start(Module, Args) ---> Module:init(Args) -> {ok, State}
%%
%% Pid ! Msg           ---> Module:handle(Msg, State) -> {ok, State}

-module(server).
-compile(export_all).

-spec start(Mod, Args) -> {ok, Pid} when
Mod :: atom(),
Args :: [term(), ...],
Pid :: pid().

start(Mod, Args)->
{ok, State} = Mod:init(Args),
Pid = spawn(?MODULE, server, [Mod, State]),
{ok, Pid}.

server(Mod, State) ->
receive
Msg ->
{ok, State1} = Mod:handle(Msg, State),
server(Mod, State1)
end.


%% @author Rolong

-module(bank_server).
-compile(export_all).

-define(I(F), io:format(F++"~n", [])).
-define(I(F, A), io:format(F++"~n", A)).

%% 银行服务使用示例:
%%
%% 创建用户:bank_server:create_account(myname, 100).
%% 用户存钱:myname ! {deposit, 10}.
%% 用户取钱:myname ! {cash1, 20}.
%%           myname ! {cash2, 30}.
%% 查询余额:myname ! check.

%%'银行开户,并存入初始金额
-spec create_account(Name, Money) -> any() when
Name :: atom(),
Money :: integer().

create_account(Name, Money)->
{ok, Pid} = server:start(?MODULE, [Money]),
%% 假设年费为10
Pid ! {yearly, 10},
erlang:register(Name, Pid).
%%.

init([Money]) ->
{ok, Money}.

%%'银行服务窗口

%%'存钱
handle({deposit, AddMoney}, Money) ->
NewMoney = Money + AddMoney,
?I("deposit money: ~w -> ~w", [Money, NewMoney]),
{ok, NewMoney};
%%.

%%'取钱(可透支)
handle({cash1, SubMoney}, Money) ->
NewMoney = Money - SubMoney,
?I("deposit money: ~w -> ~w", [Money, NewMoney]),
{ok, NewMoney};
%%.

%%'取钱(不可透支)
handle({cash2, SubMoney}, Money) ->
NewMoney = Money - SubMoney,
case NewMoney > 0 of
true ->
%% 支取成功
?I("deposit money: ~w -> ~w", [Money, NewMoney]),
{ok, NewMoney};
false ->
%% 支取失败 提示余额不足
?I("Insufficient balance, current money is ~w", [Money]),
{ok, Money}
end;
%%.

%%'扣年费(这里假设10秒为一年)
handle({yearly, Payment}, Money) ->
Year = case get(year) of
undefined ->
put(year, 0),
0;
Y ->
YY = Y + 1,
put(year, YY),
YY
end,
erlang:send_after(10 * 1000, self(), {yearly, Payment}),
Reply = if
Money =< 0 ->
%% 没有钱可以扣
Money;
Year =:= 0 ->
%% 还不到一年,不用扣
Money;
true ->
NewMoney = Money - Payment,
case NewMoney > 0 of
true ->
%% 扣费成功
?I("Yearly Payment: ~w -> ~w", [Money, NewMoney]),
NewMoney;
false ->
%% 余额不足以扣年费,则扣到0为止
?I("Yearly Payment: ~w -> ~w", [Money, 0]),
0
end
end,
{ok, Reply};
%%.

%%'查询
handle(check, Money) ->
?I("Current money is: ~w", [Money]),
{ok, Money};
%%.

%%'收到目前不受理的业务,反馈给客户
handle(Msg, Money) ->
?I("Do NOT accept business:~p", [Msg]),
{ok, Money}.
%%.

%%.

%% vim: set filetype=erlang foldmarker=%%',%%. foldmethod=marker:

%% @author Rolong
%%
%% 游戏角色使用示例:
%% 创建角色:{ok, Pid} = game_server:create_player(Id, Hp, Mp).
%% 角色加血:Pid ! {add_hp, 100}.
%% 角色加魔:Pid ! {add_mp, 100}.
%% 查看角色:Pid ! show.

-module(game_server).
-compile(export_all).

-define(I(F), io:format(F++"~n", [])).
-define(I(F, A), io:format(F++"~n", A)).

-record(state, {
id = 0
,hp = 0
,mp = 0
}).

-spec create_player(Id, Hp, Mp) -> {ok, Pid} when
Id :: integer(),
Hp :: integer(),
Mp :: integer(),
Pid :: pid().

create_player(Id, Hp, Mp) ->
server:start(?MODULE, [Id, Hp, Mp]).

init([Id, Hp, Mp]) ->
State = #state{id = Id, hp = Hp, mp = Mp},
{ok, State}.

handle({add_hp, AddHp}, #state{hp = Hp} = State) ->
NewHp = Hp + AddHp,
State1 = State#state{
hp = NewHp
},
?I("Add HP: ~w + ~w = ~w", [Hp, AddHp, NewHp]),
{ok, State1};

handle({add_mp, AddMp}, #state{mp = Mp} = State) ->
NewMp = Mp + AddMp,
State1 = State#state{
mp = NewMp
},
?I("Add MP: ~w + ~w = ~w", [Mp, AddMp, NewMp]),
{ok, State1};

handle(show, #state{id = Id, hp = Hp, mp = Mp} = State) ->
?I("ID: ~w, HP:~w, MP:~w", [Id, Hp, Mp]),
{ok, State};

handle(logout, _State) ->
?I("logout ..."),
%% TODO: Save to database ...
exit(normal);

handle(Msg, State) ->
?I("received undefined message:~p", [Msg]),
{ok, State}.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Erlang 入门教程 实例