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