Skip to content

Commit

Permalink
Merge branch 'dev' into menhir_tests
Browse files Browse the repository at this point in the history
  • Loading branch information
7h3kk1d authored Nov 4, 2024
2 parents 8b79893 + 1b6b475 commit c3de67f
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 38 deletions.
79 changes: 44 additions & 35 deletions src/haz3lweb/Main.re
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ open Haz3lweb;
open Bonsai.Let_syntax;

let scroll_to_caret = ref(true);
let edit_action_applied = ref(true);
let last_edit_action = ref(JsUtil.timestamp());

let restart_caret_animation = () =>
// necessary to trigger reflow
Expand All @@ -19,16 +17,24 @@ let restart_caret_animation = () =>
| _ => ()
};

let apply = (model, action, ~schedule_action): Model.t => {
let apply = (model, action, ~schedule_action, ~schedule_autosave): Model.t => {
restart_caret_animation();
if (UpdateAction.is_edit(action)) {
last_edit_action := JsUtil.timestamp();
edit_action_applied := true;
schedule_autosave(
BonsaiUtil.Alarm.Action.SetAlarm(
Core.Time_ns.add(Core.Time_ns.now(), Core.Time_ns.Span.of_sec(1.0)),
),
);
} else {
schedule_autosave(
BonsaiUtil.Alarm.Action.SnoozeAlarm(
Core.Time_ns.add(Core.Time_ns.now(), Core.Time_ns.Span.of_sec(1.0)),
),
);
};
if (Update.should_scroll_to_caret(action)) {
scroll_to_caret := true;
};
last_edit_action := JsUtil.timestamp();
switch (
try({
let new_model = Update.apply(model, action, ~schedule_action);
Expand All @@ -53,16 +59,6 @@ let apply = (model, action, ~schedule_action): Model.t => {
};
};

let app =
Bonsai.state_machine0(
(module Model),
(module Update),
~apply_action=
(~inject, ~schedule_event) =>
apply(~schedule_action=x => schedule_event(inject(x))),
~default_model=Model.load(Model.blank),
);

/* This subcomponent is used to run an effect once when the app starts up,
After the first draw */
let on_startup = effect => {
Expand All @@ -80,31 +76,44 @@ let on_startup = effect => {
};

let view = {
let%sub app = app;
let%sub save_scheduler = BonsaiUtil.Alarm.alarm;
let%sub app =
Bonsai.state_machine1(
(module Model),
(module Update),
~apply_action=
(~inject, ~schedule_event, input) => {
let schedule_action = x => schedule_event(inject(x));
let schedule_autosave = action =>
switch (input) {
| Active((_, alarm_inject)) =>
schedule_event(alarm_inject(action))
| Inactive => ()
};
apply(~schedule_action, ~schedule_autosave);
},
~default_model=Model.load(Model.blank),
save_scheduler,
);
let%sub () = {
on_startup(
Bonsai.Value.map(~f=((_model, inject)) => inject(Startup), app),
);
};
let%sub after_display = {
let%arr (_model, inject) = app;
if (scroll_to_caret.contents) {
scroll_to_caret := false;
JsUtil.scroll_cursor_into_view_if_needed();
};
if (edit_action_applied^
&& JsUtil.timestamp()
-. last_edit_action^ > 1000.0) {
/* If an edit action has been applied, but no other edit action
has been applied for 1 second, save the model. */
edit_action_applied := false;
print_endline("Saving...");
inject(Update.Save);
} else {
Ui_effect.Ignore;
};
let after_display = {
Bonsai.Effect.of_sync_fun(
() =>
if (scroll_to_caret.contents) {
scroll_to_caret := false;
JsUtil.scroll_cursor_into_view_if_needed();
},
(),
);
};
let%sub () = Bonsai.Edge.after_display(after_display);
let save_effect = Bonsai.Value.map(~f=((_, g)) => g(Update.Save), app);
let%sub () = BonsaiUtil.Alarm.listen(save_scheduler, ~event=save_effect);
let%sub () =
Bonsai.Edge.after_display(after_display |> Bonsai.Value.return);
let%arr (model, inject) = app;
Haz3lweb.Page.view(~inject, model);
};
Expand Down
4 changes: 3 additions & 1 deletion src/haz3lweb/Update.re
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,9 @@ let apply = (model: Model.t, update: t, ~schedule_action): Result.t(Model.t) =>
| DebugConsole(key) =>
DebugConsole.print(model, key);
Ok(model);
| Save => Model.save_and_return(model)
| Save =>
print_endline("Saving...");
Model.save_and_return(model);
| InitImportAll(file) =>
JsUtil.read_file(file, data => schedule_action(FinishImportAll(data)));
Ok(model);
Expand Down
3 changes: 2 additions & 1 deletion src/haz3lweb/dune
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@
ppx_let
ppx_sexp_conv
ppx_deriving.show
ppx_yojson_conv)))
ppx_yojson_conv
bonsai.ppx_bonsai)))

(executable
(name main)
Expand Down
42 changes: 42 additions & 0 deletions src/util/BonsaiUtil.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
open Core;
open Bonsai;
open Bonsai.Let_syntax;

module Alarm = {
module Action = {
[@deriving sexp]
type t =
| SetAlarm(Time_ns.Alternate_sexp.t)
| SnoozeAlarm(Time_ns.Alternate_sexp.t)
| UnsetAlarm;
};

let alarm =
state_machine0(
(module Time_ns.Alternate_sexp),
(module Action),
~default_model=Time_ns.max_value_representable,
~apply_action=(~inject as _, ~schedule_event as _, model, action) => {
switch (action) {
| SetAlarm(time) => time
| SnoozeAlarm(time) => Time_ns.max(time, model)
| UnsetAlarm => Time_ns.max_value_representable
}
});

let listen = (alarm, ~event) => {
let%sub before_or_after = Clock.at(alarm |> Value.map(~f=fst));
Edge.on_change(
(module Clock.Before_or_after),
before_or_after,
~callback={
open Clock.Before_or_after;
let%map (_, inject) = alarm
and event = event;
fun
| After => Effect.Many([inject(Action.UnsetAlarm), event])
| Before => Effect.Ignore;
},
);
};
};
1 change: 1 addition & 0 deletions src/util/Util.re
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module Aba = Aba;
module BonsaiUtil = BonsaiUtil;
module Direction = Direction;
module Either = Either;
module IntMap = IntMap;
Expand Down
3 changes: 2 additions & 1 deletion src/util/dune
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
js_of_ocaml-ppx
ppx_let
ppx_sexp_conv
ppx_deriving.show)))
ppx_deriving.show
bonsai.ppx_bonsai)))

(env
(dev
Expand Down

0 comments on commit c3de67f

Please sign in to comment.