Distributed Bouncing Ball

From Erlang Community

Distributed Bouncing Ball (updated to gs graphics from Erlang examples page) is classic example of Erlang distribution power.

Points to note about the code:

  • It's a distributed program.
  • It uses a platform independent graphics package gs (based on Tk/Tcl).
  • It has distributed error handing (via the link command).
  • No IDL is needed (wow - think about that one)
  • Platform independent object code is sent over the network (did you miss the one liner that did that :-)

ball.erl

-module(ball).

%% to run this program 
%% redefine the OTHERNODE macro
%%  > c(ball).
%%  > ball:install_code().
%%  > ball:run().

%% redefine this macro to your nodename
-define(OTHERNODE, 'node2@othernode.example.com').

-export([install_code/0, run/0, internal/1,loop/3]).

%% install_code() sends the code over the network
%% to my windows machine
install_code() -> 
    install_code(?MODULE).

install_code(Mod) ->
    ObjectPath = code:which(Mod),
    {ok, Bin} = file:read_file(ObjectPath),
    rpc:call(?OTHERNODE, code, load_binary,  [Mod, ObjectPath, Bin]).

run() ->
    Me    = spawn(?MODULE, internal, [true]),
    Other = spawn(?OTHERNODE, ?MODULE, internal, [false]),
    Me    ! Other,
    Other ! Me.

internal(Tag) ->
    I= gs:start(),
    W= gs:window(I,[{title,"Ball"},{width,300},{height,300},{map,true}]),
    Canvas = gs:canvas(W,[{width,300},{height,300},{bg,yellow}]),
    gs:button(W,[{label, {text,"Quit Demo"}},{x,100}]),
    gs:oval(Canvas,[{coords,[{150,150},{50,50}]},{fill,red}]),
    receive
        Pid -> 
            link(Pid),
            loop(Tag, Canvas, Pid)
    end.

loop(true, Canvas, Pid) ->
    %% I got the tag create the ball
    gs:oval(Canvas,[{coords,[{150,150},{50,50}]},{fill,red}]),
    receive
        {gs,_,click,_,["Quit Demo"]} -> exit(die);
        Other -> io:format("uugh:~p~n",[Other])
    after 2000 ->
            %% on timeout kill the ball
            gs:oval(Canvas,[{coords,[{150,150},{50,50}]},{fill,white}]),
            %% send a message to the other guy to create the ball
            Pid ! show,
            ball:loop(false, Canvas, Pid)
    end;
loop(false, Canvas, Pid) ->
    receive
        quit ->
            exit(die);
        show ->
            loop(true, Canvas, Pid)
    end.

Same example can be used to demonstrate Erlang hot code replacement.

After starting demo, you can bring up editor and change code in function loop/3 to paint ball in blue instead of red. NB! look at fully qualified function call ball:loop(false,Canvas,Pid). Erlang does code replacemant only when it encounters fully qualified function call.

Compile it and load new code.

compile and load new version of code

(node1@my_node.example.com) 3> c(code).

Now you get blue ball in at your computer. Intsall code on other node:

load new version of code on another node

(node1@my_node.example.com) 3> ball:install_code().

And You get blue ball on other node too.

Erlang/OTP Projects
Personal tools