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