Skip to content

Commit

Permalink
Breaking API Change: use traditional names for Framebuffer map like o…
Browse files Browse the repository at this point in the history
…perations.

Originally I used the names "shader", as shaders and maps work very similarly, but in documenting
the Claudius API I felt I should lean more on the obvious functional implication that the name
"map" etc. have.
  • Loading branch information
mdales committed Sep 21, 2024
1 parent 3b8f102 commit 0d5e328
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 26 deletions.
12 changes: 6 additions & 6 deletions src/framebuffer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -436,22 +436,22 @@ let draw_string (x : int) (y : int) (f : Font.t) (s : string) (col : int) (buffe

(* ----- *)

let shader (f: shader_func) (buffer : t) : t =
let map (f: shader_func) (buffer : t) : t =
Array.map (fun row ->
Array.map f row
) buffer

let shaderi (f: shaderi_func) (buffer : t) : t =
let mapi (f: shaderi_func) (buffer : t) : t =
Array.mapi (fun y row ->
Array.mapi (fun x _p -> f x y buffer) row
) buffer

let shader_inplace (f: shader_func) (buffer : t) =
let map_inplace (f: shader_func) (buffer : t) =
Array.iter (fun row ->
Array.map_inplace f row
) buffer

let shaderi_inplace (f: shaderi_func) (buffer : t) =
let mapi_inplace (f: shaderi_func) (buffer : t) =
Array.iteri (fun y row ->
Array.mapi_inplace (fun x _p -> f x y buffer) row
) buffer
Expand All @@ -477,7 +477,7 @@ let render (buffer : t) (draw : Primitives.t list) =

(* ----- *)

let merge (f : int -> int -> int) (origin : t) (delta : t) : t =
let map2 (f : int -> int -> int) (origin : t) (delta : t) : t =
try
Array.map2 (fun o_row d_row ->
Array.map2 (fun o_pixel d_pixel ->
Expand All @@ -487,7 +487,7 @@ let merge (f : int -> int -> int) (origin : t) (delta : t) : t =
with
| Invalid_argument _ -> raise (Invalid_argument "Merging framebuffers requires both to have same dimensions")

let merge_inplace (f : int -> int -> int) (origin : t) (delta : t) =
let map2_inplace (f : int -> int -> int) (origin : t) (delta : t) =
try
Array.iter2 (fun o_row d_row ->
Array.iteri (fun index d_pixel ->
Expand Down
27 changes: 15 additions & 12 deletions src/framebuffer.mli
Original file line number Diff line number Diff line change
Expand Up @@ -101,34 +101,37 @@ val draw_string: int -> int -> Font.t -> string -> int -> t -> int
{[
Framebuffer.map_inplace (fun x -> match pixel with 0 -> 0 | x -> x - 1) existing_framebuffer;
]}
All of these functions have a inplace and non_implace version: the non-implace version makes for more functional code, but
if you do it a lot the memory allocations will slow things down, and in which case you may wish to consider using inplace versions.
*)

type shader_func = int -> int

type shaderi_func = int -> int -> t -> int

val shader: shader_func -> t -> t
(** [shader f framebuffer] Generates a new framebuffer of the same dimensions by applying the provided
val map: shader_func -> t -> t
(** [map f framebuffer] Generates a new framebuffer of the same dimensions by applying the provided
function [f] to each pixel value in the original to generate a new pixel in the target. *)

val shaderi: shaderi_func -> t -> t
(** [shader f framebuffer] Generates a new framebuffer of the same dimensions by applying the provided
val mapi: shaderi_func -> t -> t
(** [mapi f framebuffer] Generates a new framebuffer of the same dimensions by applying the provided
function [f] to each pixel value and its coordinates in the original to generate a new pixel in the target. *)

val shader_inplace: shader_func -> t -> unit
(** [shader f framebuffer] Updates a framebuffer by applying the provided
val map_inplace: shader_func -> t -> unit
(** [map_inplace f framebuffer] Updates a framebuffer by applying the provided
function [f] to each pixel value to update its value. *)

val shaderi_inplace: shaderi_func -> t -> unit
(** [shader f framebuffer] Updates a framebuffer by applying the provided
val mapi_inplace: shaderi_func -> t -> unit
(** [mapi_inplace f framebuffer] Updates a framebuffer by applying the provided
function [f] to each pixel value and its coordinate value to update its value. *)

val merge: (int -> int -> int) -> t -> t -> t
(** [merge f first second] Takes two framebuffers of equal size and applys the function [f] to each pixel
val map2: (int -> int -> int) -> t -> t -> t
(** [map2 f first second] Takes two framebuffers of equal size and applys the function [f] to each pixel
pair in turn to generate a new framebuffer. *)

val merge_inplace: (int -> int -> int) -> t -> t -> unit
(** [merge_inplase f first second] Takes two framebuffers of equal size and applys the function [f] to each pixel
val map2_inplace: (int -> int -> int) -> t -> t -> unit
(** [map2_inplace f first second] Takes two framebuffers of equal size and applys the function [f] to each pixel
pair in storing the result back in the first provided framebuffer. *)


Expand Down
16 changes: 8 additions & 8 deletions test/test_framebuffer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ let test_framebuffer_write_pixel_outside _ =

let test_basic_framebuffer_shader _ =
let fb = Framebuffer.init (10, 20) (fun x y -> x + (y * 10)) in
let updated = Framebuffer.shader (fun x -> x + 1) fb in
let updated = Framebuffer.map (fun x -> x + 1) fb in
let raw = Framebuffer.to_array updated in
assert_equal ~msg:"Y axis size" 20 (Array.length raw);
Array.iteri (fun y row ->
Expand All @@ -76,7 +76,7 @@ let test_basic_framebuffer_shader _ =

let test_basic_framebuffer_shader_inplace _ =
let fb = Framebuffer.init (10, 20) (fun x y -> x + (y * 10)) in
Framebuffer.shader_inplace (fun x -> x + 1) fb;
Framebuffer.map_inplace (fun x -> x + 1) fb;
let raw = Framebuffer.to_array fb in
assert_equal ~msg:"Y axis size" 20 (Array.length raw);
Array.iteri (fun y row ->
Expand All @@ -94,7 +94,7 @@ let test_basic_framebuffer_shader_inplace _ =

let test_basic_framebuffer_shaderi _ =
let fb = Framebuffer.init (10, 20) (fun _ _ -> 0) in
let updated = Framebuffer.shaderi (fun x y _ -> (x + (y * 10))) fb in
let updated = Framebuffer.mapi (fun x y _ -> (x + (y * 10))) fb in
let raw = Framebuffer.to_array updated in
assert_equal ~msg:"Y axis size" 20 (Array.length raw);
Array.iteri (fun y row ->
Expand All @@ -114,7 +114,7 @@ let test_basic_framebuffer_shaderi _ =

let test_basic_framebuffer_shaderi_inplace _ =
let fb = Framebuffer.init (10, 20) (fun _ _ -> 0) in
Framebuffer.shaderi_inplace (fun x y _ -> (x + (y * 10))) fb;
Framebuffer.mapi_inplace (fun x y _ -> (x + (y * 10))) fb;
let raw = Framebuffer.to_array fb in
assert_equal ~msg:"Y axis size" 20 (Array.length raw);
Array.iteri (fun y row ->
Expand All @@ -133,7 +133,7 @@ let test_basic_framebuffer_shaderi_inplace _ =
let test_merge_framebuffers _ =
let fb1 = Framebuffer.init (10, 20) (fun x y -> (x + y) mod 2)
and fb2 = Framebuffer.init (10, 20) (fun x y -> 1 - ((x + y) mod 2)) in
let merged = Framebuffer.merge (fun a b -> a + b) fb1 fb2 in
let merged = Framebuffer.map2 (fun a b -> a + b) fb1 fb2 in
let raw = Framebuffer.to_array merged in
assert_equal ~msg:"Y axis size" 20 (Array.length raw);
Array.iter (fun row ->
Expand All @@ -146,7 +146,7 @@ let test_merge_framebuffers _ =
let test_merge_framebuffers_inplace _ =
let fb1 = Framebuffer.init (10, 20) (fun x y -> (x + y) mod 2)
and fb2 = Framebuffer.init (10, 20) (fun x y -> 1 - ((x + y) mod 2)) in
Framebuffer.merge_inplace (fun a b -> a + b) fb1 fb2;
Framebuffer.map2_inplace (fun a b -> a + b) fb1 fb2;
let raw = Framebuffer.to_array fb1 in
assert_equal ~msg:"Y axis size" 20 (Array.length raw);
Array.iter (fun row ->
Expand All @@ -159,12 +159,12 @@ let test_merge_framebuffers_inplace _ =
let test_merge_mismatched_framebuffers _ =
let fb1 = Framebuffer.init (10, 20) (fun x y -> (x + y) mod 2)
and fb2 = Framebuffer.init (20, 10) (fun x y -> 1 - ((x + y) mod 2)) in
assert_raises (Invalid_argument "Merging framebuffers requires both to have same dimensions") (fun _ -> Framebuffer.merge (fun a b -> a + b) fb1 fb2)
assert_raises (Invalid_argument "Merging framebuffers requires both to have same dimensions") (fun _ -> Framebuffer.map2 (fun a b -> a + b) fb1 fb2)

let test_merge_mismatched_framebuffers_inplace _ =
let fb1 = Framebuffer.init (10, 20) (fun x y -> (x + y) mod 2)
and fb2 = Framebuffer.init (20, 10) (fun x y -> 1 - ((x + y) mod 2)) in
assert_raises (Invalid_argument "Merging framebuffers requires both to have same dimensions") (fun _ -> Framebuffer.merge_inplace (fun a b -> a + b) fb1 fb2)
assert_raises (Invalid_argument "Merging framebuffers requires both to have same dimensions") (fun _ -> Framebuffer.map2_inplace (fun a b -> a + b) fb1 fb2)

let suite =
"Frambuffer tests" >::: [
Expand Down

0 comments on commit 0d5e328

Please sign in to comment.