add topbar with mana, fix bug where newly created state was not stored
in the hashtbl 😠, clean code
This commit is contained in:
parent
15d42e5038
commit
84129826b5
11 changed files with 177 additions and 89 deletions
2
src/dune
2
src/dune
|
|
@ -45,7 +45,7 @@
|
||||||
|
|
||||||
(library
|
(library
|
||||||
(name shared)
|
(name shared)
|
||||||
(modules map network state)
|
(modules log map network state time)
|
||||||
(libraries))
|
(libraries))
|
||||||
|
|
||||||
(rule
|
(rule
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,39 @@
|
||||||
open Tyxml.Html
|
open Tyxml.Html
|
||||||
open Syntax
|
open Syntax
|
||||||
|
|
||||||
let mk_img name =
|
let mk_img hidden name =
|
||||||
|
let a = [ a_id name ] in
|
||||||
img
|
img
|
||||||
~src:(Format.sprintf "/assets/img/%s.png" name)
|
~src:(Format.sprintf "/assets/img/%s.png" name)
|
||||||
~alt:name
|
~alt:name
|
||||||
~a:[ a_hidden (); a_id name ]
|
~a:(if hidden then a_hidden () :: a else a)
|
||||||
()
|
()
|
||||||
|
|
||||||
let get request =
|
let get request =
|
||||||
let** () = User.assert_logged request in
|
let** () = User.assert_logged request in
|
||||||
|
|
||||||
let title = "Your island" in
|
let title = "Your island" in
|
||||||
|
|
||||||
|
let topbar =
|
||||||
|
let mana_img = mk_img false "mana" in
|
||||||
|
let mana_lvl = span ~a:[ a_id "mana_lvl" ] [ txt "0" ] in
|
||||||
|
div ~a:[ a_class [ "centered" ] ] @@ [ mana_img; mana_lvl ]
|
||||||
|
in
|
||||||
|
|
||||||
let canvas =
|
let canvas =
|
||||||
canvas
|
canvas
|
||||||
~a:[ a_id "canvas" ]
|
~a:[ a_id "canvas" ]
|
||||||
[ txt "please update your browser or enable javascript" ]
|
[ txt "please update your browser or enable javascript" ]
|
||||||
in
|
in
|
||||||
let images =
|
|
||||||
List.map mk_img
|
let canvas_images =
|
||||||
|
List.map (mk_img true)
|
||||||
[ "grass"; "papy_left"; "papy_right"; "papy_down"; "papy_up"; "water" ]
|
[ "grass"; "papy_left"; "papy_right"; "papy_down"; "papy_up"; "water" ]
|
||||||
in
|
in
|
||||||
|
|
||||||
let page = div ~a:[ a_class [ "centered" ] ] @@ (canvas :: images) in
|
let page =
|
||||||
|
div ~a:[ a_class [ "centered" ] ] @@ (topbar :: canvas :: canvas_images)
|
||||||
|
in
|
||||||
|
|
||||||
let js =
|
let js =
|
||||||
script
|
script
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ end
|
||||||
|
|
||||||
let get_el id =
|
let get_el id =
|
||||||
match Document.find_el_by_id G.document (Jstr.of_string id) with
|
match Document.find_el_by_id G.document (Jstr.of_string id) with
|
||||||
| None -> failwith (Format.sprintf {|Could not find element by id: "%s"|} id)
|
| None -> Log.err "could not find element with id `%s`" id
|
||||||
| Some el -> el
|
| Some el -> el
|
||||||
|
|
||||||
let tile_size = 40
|
let tile_size = 40
|
||||||
|
|
@ -51,17 +51,16 @@ let papy_up = C2d.image_src_of_el (get_el "papy_up")
|
||||||
|
|
||||||
let water = C2d.image_src_of_el (get_el "water")
|
let water = C2d.image_src_of_el (get_el "water")
|
||||||
|
|
||||||
let draw =
|
let draw_canvas =
|
||||||
let papy_x = float_of_int (width - tile_size) /. 2. in
|
let papy_x = float_of_int (width - tile_size) /. 2. in
|
||||||
let papy_y = (float_of_int height /. 2.) -. (float_of_int tile_size *. 1.5) in
|
let papy_y = (float_of_int height /. 2.) -. (float_of_int tile_size *. 1.5) in
|
||||||
fun state ->
|
fun state ->
|
||||||
let open State in
|
let open State in
|
||||||
let player_x, player_y, player_dir = state.player_pos in
|
|
||||||
for x = 0 to tiles_per_w - 1 do
|
for x = 0 to tiles_per_w - 1 do
|
||||||
let map_x = x + player_x - (tiles_per_w / 2) in
|
let map_x = x + state.player_pos.x - (tiles_per_w / 2) in
|
||||||
let tile_x = float_of_int ((x * tile_size) + orig_x) in
|
let tile_x = float_of_int ((x * tile_size) + orig_x) in
|
||||||
for y = 0 to tiles_per_h - 1 do
|
for y = 0 to tiles_per_h - 1 do
|
||||||
let map_y = y + player_y - (tiles_per_h / 2) in
|
let map_y = y + state.player_pos.y - (tiles_per_h / 2) in
|
||||||
let tile_y = float_of_int ((y * tile_size) + orig_y) in
|
let tile_y = float_of_int ((y * tile_size) + orig_y) in
|
||||||
let tile_img =
|
let tile_img =
|
||||||
match Map.get_tile_kind ~x:map_x ~y:map_y state.map with
|
match Map.get_tile_kind ~x:map_x ~y:map_y state.map with
|
||||||
|
|
@ -73,7 +72,7 @@ let draw =
|
||||||
done
|
done
|
||||||
done;
|
done;
|
||||||
let papy =
|
let papy =
|
||||||
match player_dir with
|
match state.player_pos.dir with
|
||||||
| Left -> papy_left
|
| Left -> papy_left
|
||||||
| Right -> papy_right
|
| Right -> papy_right
|
||||||
| Down -> papy_down
|
| Down -> papy_down
|
||||||
|
|
@ -81,6 +80,11 @@ let draw =
|
||||||
in
|
in
|
||||||
C2d.draw_image context papy ~x:papy_x ~y:papy_y
|
C2d.draw_image context papy ~x:papy_x ~y:papy_y
|
||||||
|
|
||||||
|
let draw_topbar state =
|
||||||
|
let mana_lvl = Jv.get Jv.global "mana_lvl" in
|
||||||
|
Jv.set mana_lvl "innerHTML"
|
||||||
|
(Jv.of_string @@ string_of_int state.Shared.State.mana)
|
||||||
|
|
||||||
(* queue for action to be done *)
|
(* queue for action to be done *)
|
||||||
let input_queue = Queue.create ()
|
let input_queue = Queue.create ()
|
||||||
|
|
||||||
|
|
@ -89,8 +93,13 @@ let to_apply_queue : State.action' Queue.t = Queue.create ()
|
||||||
|
|
||||||
let send_action state action =
|
let send_action state action =
|
||||||
match State.check_action state action with
|
match State.check_action state action with
|
||||||
| Error e -> Format.printf "Invalid action: %s@\n" e
|
| Error e ->
|
||||||
| Ok _ -> Ws_client.send (Network.Action_msg action)
|
(* TODO: display this in the window *)
|
||||||
|
Log.debug "invalid action: %s@\n" e
|
||||||
|
| Ok Look_at_the_sky -> ()
|
||||||
|
| Ok _ ->
|
||||||
|
Log.debug "sending action %a to server@\n" State.pp_action action;
|
||||||
|
Ws_client.send (Network.Action_msg action)
|
||||||
|
|
||||||
let kb_handler ev =
|
let kb_handler ev =
|
||||||
let open State in
|
let open State in
|
||||||
|
|
@ -105,31 +114,31 @@ let kb_handler ev =
|
||||||
in
|
in
|
||||||
Queue.add act input_queue
|
Queue.add act input_queue
|
||||||
|
|
||||||
let last_auto_state_update = ref 0.
|
let render state =
|
||||||
|
draw_canvas state;
|
||||||
|
draw_topbar state
|
||||||
|
|
||||||
let rec game_loop state timestamp =
|
let rec game_loop state last_auto_update timestamp =
|
||||||
draw state;
|
render state;
|
||||||
let new_state =
|
let should_auto_update =
|
||||||
(* TODO repesct order of action *)
|
timestamp -. last_auto_update
|
||||||
(* apply to_apply_queue *)
|
>= Time.ms_to_float (Time.s_to_ms State.auto_update_rate)
|
||||||
|
in
|
||||||
|
|
||||||
|
let last_auto_update =
|
||||||
|
if should_auto_update then timestamp else last_auto_update
|
||||||
|
in
|
||||||
|
let state =
|
||||||
|
(* apply queue of actions *)
|
||||||
let state = Queue.fold State.perform_action state to_apply_queue in
|
let state = Queue.fold State.perform_action state to_apply_queue in
|
||||||
(* TODO can this bug because of concurrency? *)
|
|
||||||
Queue.clear to_apply_queue;
|
Queue.clear to_apply_queue;
|
||||||
(* send input action to server *)
|
(* send input action to server *)
|
||||||
Queue.iter (send_action state) input_queue;
|
Queue.iter (send_action state) input_queue;
|
||||||
Queue.clear input_queue;
|
Queue.clear input_queue;
|
||||||
|
(* state auto update *)
|
||||||
(* auto_update *)
|
if should_auto_update then State.auto_update state else state
|
||||||
if
|
|
||||||
timestamp -. !last_auto_state_update
|
|
||||||
>= float_of_int @@ (State.auto_state_update_rate * 1000)
|
|
||||||
then (
|
|
||||||
Format.printf "MANA: %d@." state.mana;
|
|
||||||
last_auto_state_update := timestamp;
|
|
||||||
State.auto_update state )
|
|
||||||
else state
|
|
||||||
in
|
in
|
||||||
G.request_animation_frame (game_loop new_state)
|
G.request_animation_frame (game_loop state last_auto_update)
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
(* init canvas *)
|
(* init canvas *)
|
||||||
|
|
@ -147,10 +156,10 @@ let () =
|
||||||
match server_msg with
|
match server_msg with
|
||||||
| Full_state _state ->
|
| Full_state _state ->
|
||||||
(* TODO reset state to received state *)
|
(* TODO reset state to received state *)
|
||||||
Format.printf "received Full_state message@\n"
|
Log.debug "received `Full_state` message@\n"
|
||||||
| Update_result res -> (
|
| Update_result res -> (
|
||||||
match res with
|
match res with
|
||||||
| Error e -> Format.printf "received update result error: %s" e
|
| Error e -> Log.debug "received update result error: %s@\n" e
|
||||||
| Ok action' -> Queue.add action' to_apply_queue ) );
|
| Ok action' -> Queue.add action' to_apply_queue ) );
|
||||||
(* bind keys *)
|
(* bind keys *)
|
||||||
let _e : Ev.listener =
|
let _e : Ev.listener =
|
||||||
|
|
@ -160,9 +169,9 @@ let () =
|
||||||
Fut.await initial_state_fut (fun msg ->
|
Fut.await initial_state_fut (fun msg ->
|
||||||
match Ws_client.to_server_msg msg with
|
match Ws_client.to_server_msg msg with
|
||||||
| Update_result _res_msg ->
|
| Update_result _res_msg ->
|
||||||
failwith
|
Log.err
|
||||||
"invalid first server message received; received Update expected \
|
"invalid first server message received; received Update expected \
|
||||||
Full_state"
|
Full_state"
|
||||||
| Full_state state ->
|
| Full_state state ->
|
||||||
(* start game *)
|
(* start game *)
|
||||||
G.request_animation_frame (game_loop state) )
|
G.request_animation_frame (game_loop state 0.) )
|
||||||
|
|
|
||||||
9
src/log.ml
Normal file
9
src/log.ml
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
let debug_on = ref true
|
||||||
|
|
||||||
|
let debug_output = ref Format.std_formatter
|
||||||
|
|
||||||
|
let debug t =
|
||||||
|
if !debug_on then Format.fprintf !debug_output t
|
||||||
|
else Format.ifprintf Format.err_formatter t
|
||||||
|
|
||||||
|
let err f = Format.kasprintf failwith f
|
||||||
43
src/map.ml
43
src/map.ml
|
|
@ -9,7 +9,30 @@ type background =
|
||||||
| Water
|
| Water
|
||||||
| Black
|
| Black
|
||||||
|
|
||||||
type position = int * int * dir
|
let pp_dir fmt dir =
|
||||||
|
let s =
|
||||||
|
match dir with
|
||||||
|
| Left -> "Left"
|
||||||
|
| Right -> "Right"
|
||||||
|
| Down -> "Down"
|
||||||
|
| Up -> "Up"
|
||||||
|
in
|
||||||
|
Format.pp_print_string fmt s
|
||||||
|
|
||||||
|
let pp_background fmt b =
|
||||||
|
let s =
|
||||||
|
match b with Grass -> "Grass" | Water -> "Water" | Black -> "Black"
|
||||||
|
in
|
||||||
|
Format.pp_print_string fmt s
|
||||||
|
|
||||||
|
type position =
|
||||||
|
{ x : int
|
||||||
|
; y : int
|
||||||
|
; dir : dir
|
||||||
|
}
|
||||||
|
|
||||||
|
let pp_position fmt p =
|
||||||
|
Format.fprintf fmt "(x = %d; y = %d; dir = %a)" p.x p.y pp_dir p.dir
|
||||||
|
|
||||||
type t =
|
type t =
|
||||||
{ tiles : background array array
|
{ tiles : background array array
|
||||||
|
|
@ -18,8 +41,8 @@ type t =
|
||||||
}
|
}
|
||||||
|
|
||||||
let init () =
|
let init () =
|
||||||
let width = 1000 in
|
let width = 100 in
|
||||||
let height = 1000 in
|
let height = 90 in
|
||||||
let tiles =
|
let tiles =
|
||||||
Array.init width (fun _x ->
|
Array.init width (fun _x ->
|
||||||
Array.init height (fun _y ->
|
Array.init height (fun _y ->
|
||||||
|
|
@ -30,17 +53,17 @@ let init () =
|
||||||
let get_tile_kind ~x ~y map =
|
let get_tile_kind ~x ~y map =
|
||||||
try map.tiles.(x).(y) with Invalid_argument _ -> Black
|
try map.tiles.(x).(y) with Invalid_argument _ -> Black
|
||||||
|
|
||||||
let check_move map entity_pos dir =
|
let check_move map ({ x; y; dir } as pos) movement_dir =
|
||||||
let x, y, current_dir = entity_pos in
|
if dir <> movement_dir then Ok { pos with dir = movement_dir }
|
||||||
let x, y =
|
|
||||||
if current_dir <> dir then (x, y)
|
|
||||||
else
|
else
|
||||||
match dir with
|
let x, y =
|
||||||
|
match movement_dir with
|
||||||
| Left -> (x - 1, y)
|
| Left -> (x - 1, y)
|
||||||
| Right -> (x + 1, y)
|
| Right -> (x + 1, y)
|
||||||
| Down -> (x, y + 1)
|
| Down -> (x, y + 1)
|
||||||
| Up -> (x, y - 1)
|
| Up -> (x, y - 1)
|
||||||
in
|
in
|
||||||
match get_tile_kind ~x ~y map with
|
match get_tile_kind ~x ~y map with
|
||||||
| Black | Water -> Error "invalid terrain"
|
| (Black | Water) as bg ->
|
||||||
| Grass -> Ok (x, y, dir)
|
Error (Format.asprintf "can't move on %a" pp_background bg)
|
||||||
|
| Grass -> Ok { pos with x; y }
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ let update_online_user_state () =
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
regularly_call_fun update_online_user_state
|
regularly_call_fun update_online_user_state
|
||||||
(float_of_int Shared.State.auto_state_update_rate);
|
(Shared.Time.s_to_float Shared.State.auto_update_rate);
|
||||||
regularly_call_fun update_offline_user_state
|
regularly_call_fun update_offline_user_state
|
||||||
(float_of_int Shared.State.auto_state_update_rate)
|
(Shared.Time.s_to_float Shared.State.auto_update_rate)
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
let logger = if App.log then Dream.logger else Fun.id in
|
let logger = if App.log then Dream.logger else Fun.id in
|
||||||
|
|
|
||||||
21
src/state.ml
21
src/state.ml
|
|
@ -4,7 +4,8 @@ type t =
|
||||||
; player_pos : Map.position
|
; player_pos : Map.position
|
||||||
}
|
}
|
||||||
|
|
||||||
let init () = { map = Map.init (); mana = 0; player_pos = (20, 3, Down) }
|
let init () =
|
||||||
|
{ map = Map.init (); mana = 0; player_pos = { x = 0; y = 0; dir = Down } }
|
||||||
|
|
||||||
type action =
|
type action =
|
||||||
| Meditate
|
| Meditate
|
||||||
|
|
@ -18,6 +19,17 @@ type action' =
|
||||||
| Set_player_position of Map.position
|
| Set_player_position of Map.position
|
||||||
| Look_at_the_sky
|
| Look_at_the_sky
|
||||||
|
|
||||||
|
let pp_action fmt = function
|
||||||
|
| Meditate -> Format.pp_print_string fmt "Meditate"
|
||||||
|
| Move dir -> Format.fprintf fmt "Move %a" Map.pp_dir dir
|
||||||
|
| Do_nothing -> Format.pp_print_string fmt "Do_nothing"
|
||||||
|
|
||||||
|
let pp_action' fmt = function
|
||||||
|
| Add_mana n -> Format.fprintf fmt "Add_mana %d" n
|
||||||
|
| Set_player_position pos ->
|
||||||
|
Format.fprintf fmt "Set_player_position (%a)" Map.pp_position pos
|
||||||
|
| Look_at_the_sky -> Format.pp_print_string fmt "Look_at_the_sky"
|
||||||
|
|
||||||
let check_action state = function
|
let check_action state = function
|
||||||
| Meditate ->
|
| Meditate ->
|
||||||
if state.mana < 99 then Ok (Add_mana 1) else Error "maximum mana"
|
if state.mana < 99 then Ok (Add_mana 1) else Error "maximum mana"
|
||||||
|
|
@ -39,4 +51,9 @@ let auto_update state =
|
||||||
let state = perform_action state action' in
|
let state = perform_action state action' in
|
||||||
state
|
state
|
||||||
|
|
||||||
let auto_state_update_rate = 5 (* in secs *)
|
let auto_update_rate = Time.mk_s 1
|
||||||
|
|
||||||
|
let pp fmt { mana; player_pos; map } =
|
||||||
|
let bg = Map.get_tile_kind ~x:player_pos.x ~y:player_pos.y map in
|
||||||
|
Format.fprintf fmt "mana = %d; player_pos = %a; %a" mana Map.pp_position
|
||||||
|
player_pos Map.pp_background bg
|
||||||
|
|
|
||||||
27
src/time.ml
Normal file
27
src/time.ml
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
include (
|
||||||
|
struct
|
||||||
|
type s = int
|
||||||
|
|
||||||
|
type ms = int
|
||||||
|
|
||||||
|
let mk_s = Fun.id
|
||||||
|
|
||||||
|
let s_to_float = float_of_int
|
||||||
|
|
||||||
|
let s_to_ms s = 1000 * s
|
||||||
|
|
||||||
|
let ms_to_float = float_of_int
|
||||||
|
end :
|
||||||
|
sig
|
||||||
|
type s
|
||||||
|
|
||||||
|
type ms
|
||||||
|
|
||||||
|
val mk_s : int -> s
|
||||||
|
|
||||||
|
val s_to_float : s -> float
|
||||||
|
|
||||||
|
val s_to_ms : s -> ms
|
||||||
|
|
||||||
|
val ms_to_float : ms -> float
|
||||||
|
end )
|
||||||
|
|
@ -233,4 +233,7 @@ let set_state = Hashtbl.replace state_ht
|
||||||
let get_state user_id =
|
let get_state user_id =
|
||||||
match Hashtbl.find_opt state_ht user_id with
|
match Hashtbl.find_opt state_ht user_id with
|
||||||
| Some state -> Ok state
|
| Some state -> Ok state
|
||||||
| None -> Ok (Shared.State.init ())
|
| None ->
|
||||||
|
let state = Shared.State.init () in
|
||||||
|
Hashtbl.replace state_ht user_id state;
|
||||||
|
Ok state
|
||||||
|
|
|
||||||
37
src/ws.ml
37
src/ws.ml
|
|
@ -1,40 +1,41 @@
|
||||||
open Lwt.Syntax
|
open Lwt.Syntax
|
||||||
open Shared
|
open Shared
|
||||||
|
|
||||||
|
let get_state_unsafe user_id =
|
||||||
|
match User.get_state user_id with
|
||||||
|
| Error _e -> assert false
|
||||||
|
| Ok state -> state
|
||||||
|
|
||||||
let handle_client request client =
|
let handle_client request client =
|
||||||
match Dream.session "user_id" request with
|
match Dream.session "user_id" request with
|
||||||
| None -> Dream.log "User does not exists" |> Lwt.return
|
| None -> Dream.log "User does not exists" |> Lwt.return
|
||||||
| Some user_id ->
|
| Some user_id ->
|
||||||
(* TODO catch marshal failure *)
|
(* send user island state for the first time *)
|
||||||
let state =
|
let state = get_state_unsafe user_id in
|
||||||
match User.get_state user_id with
|
|
||||||
| Error _e -> assert false
|
|
||||||
| Ok state -> state
|
|
||||||
in
|
|
||||||
let state_msg = Network.Full_state state in
|
|
||||||
|
|
||||||
(* send user island state *)
|
|
||||||
let* () =
|
let* () =
|
||||||
Dream.send ~text_or_binary:`Text client (Network.marshal state_msg)
|
Dream.send ~text_or_binary:`Text client
|
||||||
|
(Network.marshal (Network.Full_state state))
|
||||||
in
|
in
|
||||||
|
|
||||||
let rec loop () =
|
let rec loop () =
|
||||||
match%lwt Dream.receive client with
|
match%lwt Dream.receive client with
|
||||||
| None -> Dream.close_websocket client
|
| None ->
|
||||||
|
(* TODO: backup everything to database *)
|
||||||
|
Dream.close_websocket client
|
||||||
| Some s ->
|
| Some s ->
|
||||||
let state =
|
let state = get_state_unsafe user_id in
|
||||||
match User.get_state user_id with
|
|
||||||
| Error _e -> assert false
|
|
||||||
| Ok state -> state
|
|
||||||
in
|
|
||||||
let (Network.Action_msg action : Network.client_message) =
|
let (Network.Action_msg action : Network.client_message) =
|
||||||
Network.unmarshal s
|
Network.unmarshal s
|
||||||
in
|
in
|
||||||
|
Dream.log "checking action %a" State.pp_action action;
|
||||||
|
Dream.log "current state %a" State.pp state;
|
||||||
let res =
|
let res =
|
||||||
match State.check_action state action with
|
match State.check_action state action with
|
||||||
| Error _e as error -> error
|
| Error msg as e ->
|
||||||
|
Dream.log "check_action error: %s" msg;
|
||||||
|
e
|
||||||
| Ok action' ->
|
| Ok action' ->
|
||||||
(* update server state *)
|
Dream.log "check_action ok: %a" State.pp_action' action';
|
||||||
let state = State.perform_action state action' in
|
let state = State.perform_action state action' in
|
||||||
User.set_state user_id state;
|
User.set_state user_id state;
|
||||||
Ok action'
|
Ok action'
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ open Brr_io
|
||||||
open Shared
|
open Shared
|
||||||
|
|
||||||
let ws =
|
let ws =
|
||||||
Format.printf "create websocket@\n";
|
|
||||||
let ws_url =
|
let ws_url =
|
||||||
let location = Window.location G.window in
|
let location = Window.location G.window in
|
||||||
let host = Uri.host location |> Jstr.to_string in
|
let host = Uri.host location |> Jstr.to_string in
|
||||||
|
|
@ -18,30 +17,18 @@ let ws =
|
||||||
|
|
||||||
let ws_target = Websocket.as_target ws
|
let ws_target = Websocket.as_target ws
|
||||||
|
|
||||||
let on_event ws_event log_msg f =
|
let on_event ws_event f =
|
||||||
let (_ : Ev.listener) =
|
let (_ : Ev.listener) = Ev.listen ws_event f ws_target in
|
||||||
Ev.listen ws_event
|
|
||||||
(fun ev ->
|
|
||||||
Format.printf "%s@\n" log_msg;
|
|
||||||
f ev )
|
|
||||||
ws_target
|
|
||||||
in
|
|
||||||
()
|
()
|
||||||
|
|
||||||
let to_server_msg ev =
|
let to_server_msg ev =
|
||||||
Format.printf "to_server_msg@.";
|
|
||||||
let data = Message.Ev.data (Ev.as_type ev) |> Jstr.to_string in
|
let data = Message.Ev.data (Ev.as_type ev) |> Jstr.to_string in
|
||||||
let server_msg : Network.server_message = Network.unmarshal data in
|
let server_msg : Network.server_message = Network.unmarshal data in
|
||||||
Format.printf "un-marshaled message from server yay ~ @\n";
|
|
||||||
server_msg
|
server_msg
|
||||||
|
|
||||||
let on_update_state_message f =
|
let on_update_state_message f =
|
||||||
on_event Message.Ev.message "Websocket reveived message!" (fun ev ->
|
on_event Message.Ev.message (fun ev -> f (to_server_msg ev))
|
||||||
f (to_server_msg ev) )
|
|
||||||
|
|
||||||
let send (msg : Network.client_message) =
|
let send (msg : Network.client_message) =
|
||||||
Format.printf "send msg on websocket ~~ @\n";
|
|
||||||
let s = Jstr.of_string (Network.marshal msg) in
|
let s = Jstr.of_string (Network.marshal msg) in
|
||||||
Websocket.send_string ws s;
|
Websocket.send_string ws s
|
||||||
Format.printf "send action on websocket ~~ DONE @\n";
|
|
||||||
()
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue