Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor option double match to use combinators. #2

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library/Makefile-world
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SOURCES = world.mli world.ml
SOURCES = option.ml world.mli world.ml
PACKS = cairo2.lablgtk2 lablgtk2.gnomecanvas
RESULT = world
OCAMLMAKEFILE = ../OCamlMakefile
Expand Down
5 changes: 5 additions & 0 deletions library/option.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@


let orElse d = function Some v -> Some v | None -> Lazy.force d

let iter f = function Some v -> f v | None -> ()
23 changes: 7 additions & 16 deletions library/universe.ml
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,17 @@ let universe ?(on_new=initial_new)

(* universe 内で使う各種関数群 *)

let reset_flag = ref false in
(* trueになったらstateの初期値を返してサーバをリセット *)


(* client_sockfdをもらったらそれを通信からはずす *)
(* client_sockfdをcloseする *)
let rec cut_communication client_sockfd =
(* client_sockfdをcloseする. *)
let cut_communication client_sockfd =
if List.mem_assoc client_sockfd !clientlst then
begin
clientlst := List.remove_assoc client_sockfd !clientlst;
Socket.close client_sockfd;
if !clientlst = [] then
reset_flag := true
end
(* もしもともと通信から抜けていたら何もしない *)
in

(* update_and_send : 'a * 'b list * iworld_t list -> unit *)
(* 状態を更新し、メールを送る。ここが唯一の state を変更する場所 *)
(* iworldlstは通信から外したいクライアントのリスト。これが空でないとループ *)
Expand All @@ -87,15 +81,12 @@ let universe ?(on_new=initial_new)
Socket.send None first;
(* クライアントにもう送らないでねって合図を送る *)
GMain.Io.remove (List.assoc first !clientlst);
(* add_watchの登録を解除 *)
cut_communication first;
(* 通信を切る処理 *)
if !reset_flag
(* add_watchの登録を解除. *)
cut_communication first;
(* すべてのクライアントがいなくなったら、状態リセット *)
if !clientlst = []
then
begin
state := initial_state;
reset_flag := false
end
state := initial_state
else
update_and_send (Bundle (!state, maillst, rest))
(* restとmailの処理 *)
Expand Down
13 changes: 4 additions & 9 deletions library/world.ml
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,9 @@ let big_bang ?(name="My Game")

(*まずサーバーに登録*)
(*クライアントのソケットとサーバのソケットの接続*)
let register' = match register with
None -> obtain_addrinfo ()
| Some (_, _) -> register
in
(* ここの match 文の連続はもう少しきれいにならないかと思うが... *)
begin match register' with
None -> ()
| Some (ipaddress, portnumber) ->
register
|> Option.orElse (lazy (obtain_addrinfo ()))
|> Option.iter (fun (ipaddress, portnumber) -> begin
Socket.connect (ipaddress, portnumber) server_sockfd;
(*ignore (GMain.Io.add_watch ~cond:[`IN]
~callback:receive_event
Expand All @@ -306,7 +301,7 @@ let big_bang ?(name="My Game")
~callback:receive_event
~prio:(Glib.int_of_priority `LOW)
(GMain.Io.channel_of_descr server_sockfd));
end;
end);

(* ここで最初の画面の表示 *)
update_and_draw (World !world);
Expand Down