Skip to content

Commit

Permalink
Eio backend for JavaScript environments
Browse files Browse the repository at this point in the history
This provides:
- `eio_js_backend`, a simple backend;
- `js_of_ocaml-eio`, a counterpart to `js_of_ocaml-lwt`;
- `eio_brr`, Eio support for Brr (Eio variants of Brr functions
  that returns directly instead of returning a future).
  • Loading branch information
vouillon committed Feb 8, 2024
1 parent 464a562 commit 33d8d43
Show file tree
Hide file tree
Showing 86 changed files with 8,631 additions and 0 deletions.
20 changes: 20 additions & 0 deletions dune-project
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,24 @@
(or (<> :os-distribution "centos") (> :os-version 7))))
(eio_posix (and (= :version) (<> :os "win32")))
(eio_windows (and (= :version) (= :os "win32")))))
(package
(name eio_js_backend)
(synopsis "Simple Eio scheduler for JavaScript environments")
(description "An Eio scheduler suitable for JavaScript environments.")
(depends
(eio (= :version))))
(package
(name eio_brr)
(synopsis "Eio support for Brr")
(description "This package provides Eio variants of Brr functions, which returns directly instead of returning a future.")
(depends
(eio_js_backend (= :version))
(brr (>= 0.0.4))))
(package
(name js_of_ocaml-eio)
(synopsis "Eio-based JavaScript bindings")
(description "An Eio counterpart to package js_of_ocaml-lwt.")
(depends
(eio_js_backend (= :version))
(js_of_ocaml (>= 5.0.1))))
(using mdx 0.2)
32 changes: 32 additions & 0 deletions eio_brr.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "Eio support for Brr"
description:
"This package provides Eio variants of Brr functions, which returns directly instead of returning a future."
maintainer: ["anil@recoil.org"]
authors: ["Anil Madhavapeddy" "Thomas Leonard"]
license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
doc: "https://ocaml-multicore.github.io/eio/"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "3.9"}
"eio" {= version}
"brr" {>= "0.0.4"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"
30 changes: 30 additions & 0 deletions eio_js_backend.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "Simple Eio scheduler for JavaScript environments"
description: "An Eio scheduler suitable for JavaScript environments."
maintainer: ["anil@recoil.org"]
authors: ["Anil Madhavapeddy" "Thomas Leonard"]
license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
doc: "https://ocaml-multicore.github.io/eio/"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "3.9"}
"eio" {= version}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"
31 changes: 31 additions & 0 deletions js_of_ocaml-eio.opam
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# This file is generated by dune, edit dune-project instead
opam-version: "2.0"
synopsis: "Eio-based JavaScript bindings"
description: "An Eio counterpart of package js_of_ocaml-lwt."
maintainer: ["anil@recoil.org"]
authors: ["Anil Madhavapeddy" "Thomas Leonard"]
license: "ISC"
homepage: "https://github.com/ocaml-multicore/eio"
doc: "https://ocaml-multicore.github.io/eio/"
bug-reports: "https://github.com/ocaml-multicore/eio/issues"
depends: [
"dune" {>= "3.9"}
"eio" {= version}
"js_of_ocaml" {>= "5.0.1"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {dev}
[
"dune"
"build"
"-p"
name
"-j"
jobs
"@install"
"@runtest" {with-test}
"@doc" {with-doc}
]
]
dev-repo: "git+https://github.com/ocaml-multicore/eio.git"
6 changes: 6 additions & 0 deletions lib_eio_brr/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(library
(name eio_brr)
(public_name eio_brr)
(wrapped false)
(modes byte)
(libraries eio_js_backend brr))
46 changes: 46 additions & 0 deletions lib_eio_brr/eio_brr.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
let start = Eio_js_backend.start

module Blob = struct
let array_buffer b = Eio_fut.await_exn (Brr.Blob.array_buffer b)
let text b = Eio_fut.await_exn (Brr.Blob.text b)
let data_uri b = Eio_fut.await_exn (Brr.Blob.data_uri b)
end

module Ev = struct
let next ?capture typ target = Eio_fut.await (Brr.Ev.next ?capture typ target)

module Data_transfer = struct
module Item = struct
let get_jstr i = Eio_fut.await (Brr.Ev.Data_transfer.Item.get_jstr i)
end
end

module Extendable = struct
let wait_until e ~sw f =
Brr.Ev.Extendable.wait_until e (Eio_fut.make_exn ~sw f)
end
end

module El = struct
let request_pointer_lock e = Eio_fut.await_exn (Brr.El.request_pointer_lock e)

let request_fullscreen ?opts e =
Eio_fut.await_exn (Brr.El.request_fullscreen ?opts e)
end

module Document = struct
let exit_pointer_lock e = Eio_fut.await (Brr.Document.exit_pointer_lock e)
let exit_fullscreen e = Eio_fut.await_exn (Brr.Document.exit_fullscreen e)
end

module G = struct
let set_timeout ~ms =
Eio_js_backend.await
~setup:(fun ~resolve ~reject:_ -> Brr.G.set_timeout ~ms resolve)
~cancel:Brr.G.stop_timer

let request_animation_frame () =
Eio_js_backend.await
~setup:(fun ~resolve ~reject:_ -> Brr.G.request_animation_frame resolve)
~cancel:Brr.G.cancel_animation_frame
end
100 changes: 100 additions & 0 deletions lib_eio_brr/eio_brr.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
(** {1 Eio scheduler setup} *)

val start : (unit -> unit) -> unit
(** [start f] executes function [f] asynchronously in a context where
Eio operations can be performed.
This function is an alias for {!Eio_js_scheduler.start}.
*)

(** {1 Eio variants of Brr functions} *)

(** {2:data Data containers and encodings} *)

(** Blob objects. *)
module Blob : sig
val array_buffer : Brr.Blob.t -> Brr.Tarray.Buffer.t
(** [array_buffer b] is an
{{:https://developer.mozilla.org/en-US/docs/Web/API/Blob/arrayBuffer}
array buffer} with the contents of [b]. *)

val text : Brr.Blob.t -> Jstr.t
(** [text b] is the
{{:https://developer.mozilla.org/en-US/docs/Web/API/Blob/text}string}
that results from UTF-8 decoding the contents of [b]. *)

val data_uri : Brr.Blob.t -> Jstr.t
(** [data_uri b] is [b] as a data URI (via the
{{:https://developer.mozilla.org/en-US/docs/Web/API/FileReader}
[FileReader]} API). *)
end

(** {2 DOM interaction} *)

(** DOM events. *)
module Ev : sig
val next : ?capture:bool -> 'a Brr.Ev.type' -> Brr.Ev.target -> 'a Brr.Ev.t
(** [next type' t] returns the next event of type [type'] on target [t]. *)

(** [DataTransfer] objects. *)
module Data_transfer : sig
(** [DataTransferItem] objects. *)
module Item : sig
val get_jstr : Brr.Ev.Data_transfer.Item.t -> Jstr.t
(** [get_jstr i] is the item's text. *)
end
end

module Extendable : sig
val wait_until :
Brr.Ev.Extendable.t -> sw:Eio.Switch.t -> (unit -> _) -> unit
(** [wait_until e ~sw fn] {{:https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/waitUntil}indicates} to the event dispatcher that work is ongoing. Function [fn] is run in a new fiber attached to [sw]. The work is considered completed when [fn] returns. *)
end
end

(** DOM elements. *)
module El : sig
(** {1 Pointer locking} *)

val request_pointer_lock : Brr.El.t -> unit
(** [request_pointer_lock e] requests the pointer to be locked
to [e] in the document it belongs to. This listens on the
document for the next [Brr.Ev.pointerlockchange] and
[Brr.Ev.pointerlockerror] to resolve the future appropriately. *)

(** {1 Fullscreen} *)

val request_fullscreen : ?opts:Brr.El.fullscreen_opts -> Brr.El.t -> unit
(** [request_fullscreen e] requests to make the element
to be displayed in fullscreen mode. *)
end

(** [Document] objects *)
module Document : sig
(** {1 Pointer locking} *)

val exit_pointer_lock : Brr.Document.t -> unit
(** [exit_pointer_lock d] {{:https://developer.mozilla.org/en-US/docs/Web/API/Document/exitPointerLock}exits} pointer lock mode. This returns
when the corresponding [Brr.Ev.pointerlockchange] on [d] has fired. *)

(** {1 Fullscreen}
Use {!El.request_fullscreen} to get into fullscreen mode. *)

val exit_fullscreen : Brr.Document.t -> unit
(** [exit_fullscreen d]
{{:https://developer.mozilla.org/en-US/docs/Web/API/Document/exitFullscreen}exits} fullscreen mode. *)
end

(** The global object, its global objects and functions. *)
module G : sig
val set_timeout : ms:int -> unit
(** [set_timeout ~ms] is a timer waiting for [ms] milliseconds. It
can be cancelled. *)

val request_animation_frame : unit -> float
(** [request_animation_frame ()]
{{:https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame}waits}
until right before the next repaint. It returns the current
point in time. It can be cancelled. *)
end
4 changes: 4 additions & 0 deletions lib_eio_brr/eio_brr_canvas.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Canvas = struct
let to_blob ?encode c =
Eio_fut.await_exn (Brr_canvas.Canvas.to_blob ?encode c)
end
10 changes: 10 additions & 0 deletions lib_eio_brr/eio_brr_canvas.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
(** Canvas element. *)
module Canvas : sig
val to_blob :
?encode:Brr_canvas.Canvas.image_encode ->
Brr_canvas.Canvas.t ->
Brr.Blob.t option
(** [to_blob ~encode t] is the canvas's image a blob object. [None]
is returned either if the canvas has no pixels or if an error
occurs during image serialisation. *)
end
Loading

0 comments on commit 33d8d43

Please sign in to comment.