1    type App =
2        let name : String
3        let is_resizable @param = false
4        val os_window = OsWindow.create 1920 1080 name is_resizable
5        Glfw.set_window_size_limits os_window.window 1200 600 Glfw.dont_care
6                                    Glfw.dont_care
7        Glfw.make_context_current os_window.window
8        val display = Display os_window
9        val mouse = Mouse.create os_window display.overlay.controls
10                                display.controls display.focus@atom
11   
12       val captured@atom = mouse.capture@atom.option_map { _.control }
13       val tick = Stream<f32>.new
14       let presenter = Presenter.new
15       let canvas = Canvas presenter
16   
17       display.controls.add canvas
18   
19       let f (control : Control) =
20           control.set_fixed_width os_window.width
21                   set_fixed_height os_window.height
22   
23       f canvas
24       f presenter
25   
26       let size_token = os_window.sizes.subscribe {
27           f canvas
28           f presenter }
29   
30       def run =
31           let frame_length_micros = 1000 / 0.06 |> as<u64>
32           let mut last_frame_time = Time.now - Duration 1 0
33           while not self.os_window.should_close do
34               repeat
35                   let elapsed_micros = last_frame_time.elapsed.to_microseconds
36                   if elapsed_micros + 200 >= frame_length_micros then
37                       break
38                   else
39                       let sleep_duration =
40                           frame_length_micros - elapsed_micros - 150
41                           |> Duration.from_microseconds
42   
43                       thread/sleep sleep_duration
44   
45               while frame_length_micros > last_frame_time.elapsed.to_microseconds
46               do
47                   thread/yield
48   
49               let dt = last_frame_time.elapsed.to_seconds_f32 |> min 0.049
50               last_frame_time = Time.now
51               os_window.update
52               glfw/update
53               tick.push dt
54   
55       def add_window (window : Window) =
56           canvas.items.add window
57           bring_to_front window
58   
59       val remove_window = { window ->
60           canvas.items.remove window
61   
62           if captured.is_some && window.contains captured.unwrap then
63               mouse.capture = None }<Window>
64   
65       def contains_window (window : Window) =
66           canvas.items.contains window
67   
68       def top_control =
69           let control = canvas.items[0]
70           if control is Window && control.as<Window>.header == "console"
71           then canvas.items[1]
72           else control
73   
74       def set_content (content : Option<Control>) =
75           presenter.content = content
76   
77       def discard =
78           size_token.discard
79           os_window.discard
80           Glfw.terminate
81   
82   type Dependencies =
83       val os_window : OsWindow
84       val captured : Atom<Option<Control>>
85       val remove_window : Window -> Unit
86       val overlay : Overlay
87   
88   type App
89       val dependencies = Dependencies
90           =os_window
91           captured = captured@atom
92           =remove_window
93           overlay = display.overlay
94