Sophie

Sophie

distrib > Fedora > 18 > x86_64 > media > updates > by-pkgid > 3866615ed9f87500bac83f78574eecc8 > files > 362

js-of-ocaml-doc-1.2-2.fc18.noarch.rpm

(* Js_of_ocaml example
 * http://www.ocsigen.org/js_of_ocaml/
 * Copyright (C) 2010 Jérôme Vouillon
 * Laboratoire PPS - CNRS Université Paris Diderot
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *)

let n = 12

let h = 20.
let w = floor (h *. sqrt 3. /. 2. +. 0.5)

(****)

let _ = Random.self_init ()

let create_cubes v =
  Array.init n (fun _ -> Array.init n (fun _ -> Array.make n v))

let get a i j k =
  i < 0 || j < 0 || k < 0 ||
  (i < n && j < n && k < n && a.(i).(j).(k))

let update a =
  let i = Random.int n in
  let j = Random.int n in
  let k = Random.int n in
  if a.(i).(j).(k) then begin
    if
      not (get a (i + 1) j k || get a i (j + 1) k || get a i j (k + 1))
    then begin
      a.(i).(j).(k) <- false;
      true
    end else
      false
  end else begin
    if get a (i - 1) j k & get a i (j - 1) k && get a i j (k - 1) then begin
      a.(i).(j).(k) <- true;
      true
    end else
      false
  end

(****)

module Html = Dom_html

let top = Js.string "#a8a8f6"
let left = Js.string "#d9d9d9"
let right = Js.string "#767676"
let edge = Js.string "#000000"

let on_cube c i j k f =
  let x = float (i - k + n - 1) *. w in
  let y = float (n - 1 - j) *. h +. float (i + k) *. h /. 2. in
  c##save ();
  c##translate (x, y);
  f c;
  c##restore ()

let draw_top c =
  c##fillStyle <- top;
  c##beginPath ();
  c##moveTo (w, 0.);
  c##lineTo (2. *. w, h /. 2.);
  c##lineTo (w, h);
  c##lineTo (0., h /. 2.);
  c##fill ()

let top_edges c =
  c##beginPath ();
  c##moveTo (0., h /. 2.);
  c##lineTo (w, 0.);
  c##lineTo (2. *. w, h /. 2.);
  c##stroke ()

let draw_right c =
  c##fillStyle <- right;
  c##beginPath ();
  c##moveTo (w, h);
  c##lineTo (w, 2. *. h);
  c##lineTo (2. *. w, 1.5 *. h);
  c##lineTo (2. *. w, h /. 2.);
  c##fill ()

let right_edges c =
  c##beginPath ();
  c##moveTo (w, 2. *. h);
  c##lineTo (w, h);
  c##lineTo (2. *. w, h /. 2.);
  c##stroke ()

let draw_left c =
  c##fillStyle <- left;
  c##beginPath ();
  c##moveTo (w, h);
  c##lineTo (w, 2. *. h);
  c##lineTo (0., 1.5 *. h);
  c##lineTo (0., h /. 2.);
  c##fill ()

let left_edges c =
  c##beginPath ();
  c##moveTo (w, h);
  c##lineTo (0., h /. 2.);
  c##lineTo (0., 1.5 *. h);
  c##stroke ()

let remaining_edges c =
  c##beginPath ();
  c##moveTo (0., float n *. 1.5 *. h);
  c##lineTo (float n *. w, float n *. 2. *. h);
  c##lineTo (float n *. 2. *. w, float n *. 1.5 *. h);
  c##lineTo (float n *. 2. *. w, float n *. 0.5 *. h);
  c##stroke ()

let tile c a (top, right, left) =
  for i = 0 to n - 1 do
    let j = ref (n - 1) in
    for k = 0 to n - 1 do
      while (!j >= 0 && not a.(i).(!j).(k)) do decr j done;
      on_cube c i !j k top
    done
  done;
  for j = 0 to n - 1 do
    let i = ref (n - 1) in
    for k = 0 to n - 1 do
      while (!i >= 0 && not a.(!i).(j).(k)) do decr i done;
      on_cube c !i j k right
    done
  done;
  for i = 0 to n - 1 do
    let k = ref (n - 1) in
    for j = 0 to n - 1 do
      while (!k >= 0 && not a.(i).(j).(!k)) do decr k done;
      on_cube c i j !k left
    done
  done

let create_canvas () =
  let d = Html.window##document in
  let c = Html.createCanvas d in
  c##width <- n * 2 * truncate w + 1;
  c##height <- n * 2 * truncate h + 1;
  c

let redraw ctx canvas a =
  let c = canvas##getContext (Html._2d_) in
  c##setTransform (1., 0., 0., 1., 0., 0.);
  c##clearRect (0., 0., float canvas##width, float canvas##height);
  c##setTransform (1., 0., 0., 1., 0.5, 0.5);
  c##globalCompositeOperation <- Js.string "lighter";
  tile c a (draw_top, draw_right, draw_left);
  c##globalCompositeOperation <- Js.string "source-over";
  tile c a (top_edges, right_edges, left_edges);
  remaining_edges c;
  ctx##drawImage_fromCanvas (canvas, 0., 0.)

let (>>=) = Lwt.bind

let rec loop c c' a =
  Lwt_js.sleep 0.2 >>= fun () ->
  let need_redraw = ref false in
  for i = 0 to 99 do
    need_redraw := update a || !need_redraw
  done;
  if !need_redraw then redraw c c' a;
  loop c c' a

let start _ =
  let c = create_canvas () in
  let c' = create_canvas () in
  Dom.appendChild Html.window##document##body c;
  let c = c##getContext (Html._2d_) in
  c##globalCompositeOperation <- Js.string "copy";
  let a = create_cubes true in
  redraw c c' a;
  ignore (loop c c' a);
  Js._false

let _ =
Html.window##onload <- Html.handler start