I think that your state should include a status telling if you are Loading
or Running
the application :
type t =
{ status : [`Loading | `Running ]
; data : …
}
As long as you do not store functionnal values inside the state, you can add as many elements as you want (if you want to add such elements in the state, you have to provide your own compare
function in order to avoid error in runtime).
Then, here is how I run my event loop: each event is handled inside it’s own module and I avoid the monolithic pattern matching:
(** The Make module build the main application loop.
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
(** Decrement 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 events *)
let incr_event = App.E ((), (module Incr:App.Event with type t = Incr.t))
let decr_event = App.E ((), (module Decr:App.Event with type t = Decr.t))
let init = { value = 0 } in
(* Run the main loop *)
let state = App.run
init
(E.select
[ incr_event
; decr_event ] ) in …
]
*)
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
I have applied this pattern in differents applications, and this works fine. I’ve found the inspiration in this post : The shape design problem - #26 by kantian
Hope this helps