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