package miaou-core
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
Miaou core/widgets (no drivers, no SDL)
Install
dune-project
Dependency
Authors
Maintainers
Sources
v0.5.2.tar.gz
md5=60a3b9f181f24572a06a9492532bfdda
sha512=fcc35a275066be2900e6201782faf47503076fa4640f08cf78067835a6f447b74613009e55b2ac799adb7ca46f1bffa261fc5971753f2cc3c6bef327511c7ef6
doc/src/miaou-core.interfaces/timer.ml.html
Source file timer.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114(*****************************************************************************) (* *) (* SPDX-License-Identifier: MIT *) (* Copyright (c) 2025 Nomadic Labs <contact@nomadic-labs.com> *) (* *) (*****************************************************************************) [@@@warning "-32-34-37-69"] type kind = Interval | Timeout type timer_entry = { id : string; kind : kind; interval_s : float; mutable deadline : float; } type state = {mutable timers : timer_entry list; mutable fired : string list} type t = { set_interval : id:string -> float -> unit; set_timeout : id:string -> float -> unit; clear : string -> unit; drain_fired : unit -> string list; active_ids : unit -> string list; } let key : t Capability.key = Capability.create ~name:"Timer" let set v = Capability.set key v let get () = Capability.get key let require () = Capability.require key let create_state () = {timers = []; fired = []} let register (s : state) = let cap : t = { set_interval = (fun ~id interval_s -> let clock = Clock.require () in let now = clock.now () in (* Remove any existing timer with same id *) s.timers <- List.filter (fun e -> e.id <> id) s.timers ; let entry = {id; kind = Interval; interval_s; deadline = now +. interval_s} in s.timers <- entry :: s.timers); set_timeout = (fun ~id delay_s -> let clock = Clock.require () in let now = clock.now () in s.timers <- List.filter (fun e -> e.id <> id) s.timers ; let entry = { id; kind = Timeout; interval_s = delay_s; deadline = now +. delay_s; } in s.timers <- entry :: s.timers); clear = (fun id -> s.timers <- List.filter (fun e -> e.id <> id) s.timers); drain_fired = (fun () -> let f = s.fired in s.fired <- [] ; f); active_ids = (fun () -> List.map (fun e -> e.id) s.timers); } in set cap let tick (s : state) = let clock = Clock.require () in let now = clock.now () in let fired = ref [] in let remaining = ref [] in List.iter (fun (entry : timer_entry) -> if now >= entry.deadline then begin fired := entry.id :: !fired ; match entry.kind with | Interval -> (* Reschedule: advance deadline by interval. If we missed multiple intervals (e.g. long tick), snap to next future deadline rather than firing a burst. *) let next = entry.deadline +. entry.interval_s in let next = if next <= now then (* We're behind — snap to the next future deadline *) let missed = Float.to_int ((now -. entry.deadline) /. entry.interval_s) in entry.deadline +. (float_of_int (missed + 1) *. entry.interval_s) else next in entry.deadline <- next ; remaining := entry :: !remaining | Timeout -> (* One-shot: don't keep it *) () end else remaining := entry :: !remaining) s.timers ; s.timers <- List.rev !remaining ; s.fired <- List.rev_append !fired s.fired let clear_all (s : state) = s.timers <- [] ; s.fired <- []
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>