From 52cbf99e0db1c0fb7b44f4101c6a673d9ec1fbbe Mon Sep 17 00:00:00 2001
From: Sébastien Dailly <sebastien@dailly.me>
Date: Mon, 7 Feb 2022 15:48:26 +0100
Subject: Update application workflow

---
 lib/application/application.ml | 58 +++++++++++++++++++++++++++++++++++-------
 1 file changed, 49 insertions(+), 9 deletions(-)

(limited to 'lib/application')

diff --git a/lib/application/application.ml b/lib/application/application.ml
index 15452fb..63e12ba 100755
--- a/lib/application/application.ml
+++ b/lib/application/application.ml
@@ -1,9 +1,49 @@
-(** The type for the applcation *)
-type ('a, 'b) t = 'a -> 'b -> 'b
-
-(** Simple helper for the main event loop *)
-let run
-  : ?eq:('b -> 'b -> bool) -> ('a, 'b) t -> 'b -> 'a Note.E.t -> 'b Note.S.t
-  = fun ?eq f init event ->
-    let action = Note.E.map f event in
-    Note.S.accum ?eq init action
+(** The Make module build the main application loop.contents
+
+    The function [run] update the state on each event, and return a new state.
+    Each event must follow the [event] type, which is composed from the type
+    [t], and a module with a fonction [update].
+
+    This example create an application with the state containing a simple
+    counter. An even which increment this counter is created and can be used to
+    update the state.
+
+
+    [
+        type state = { value : int }
+
+        (** Increment the state *)
+        module Incr = struct
+            type t = unit
+
+            let update () state = { value = state.value + 1 }
+        end
+
+        module App = Make(struct type t = state end)
+
+        (* Create the event itself *)
+        let incr_event = App.E ((), (module Incr:App.Event with type t = Incr.t))
+
+    ]
+
+*)
+module Make(S:sig type t end) = struct
+  module type Event = sig
+
+    type t
+
+    val update: t -> S.t -> S.t
+
+  end
+
+  type event = E : 'a * (module Event with type t = 'a) -> event
+
+  (** Simple helper for the main event loop *)
+  let run
+    : ?eq:(S.t -> S.t -> bool) -> S.t -> event Note.E.t -> S.t Note.S.t
+    = fun ?eq init event ->
+      let action = Note.E.map (fun (E (t, (module Event))) st -> Event.update t st) event in
+      Note.S.accum ?eq init action
+end
+
+
-- 
cgit v1.2.3