1     typealias GetImage = String -> Atom<Option<Image>>
2     typealias GetFont = String -> Font
3     typealias GetMesh = String -> Mesh
4     
5     type Resources =
6         let command_buffer : CommandBuffer
7         let buffer_pool : BufferPool
8         val get_image : GetImage
9         val get_font : GetFont
10        val get_mesh : GetMesh
11        val get_shader : GetShader
12        val shader_path : String
13        val shader_source_path : String
14        val shader_directory : Directory<ShaderFile, Shader>
15        val image_directory : Directory<ImageMemory, Image>
16        val mesh_directory : Directory<MeshFile, Mesh>
17        val font_directory : Directory<FontFile, Font>
18        val image_changed : Stream<String>
19    
20    let get_shader_directory (directory_path : String) =
21        let g (path_files : obs/Map<String, ShaderFile>) =
22            path_files |> Obs.map { path file -> when
23                path.ends_with ".vert" ->
24                    VertexShader.create path file.bytes file.metadata
25    
26                path.ends_with ".frag" ->
27                    FragmentShader.create path file.bytes file.metadata
28    
29                path.ends_with ".comp" ->
30                    ComputeShader.create path file.bytes file.metadata
31    
32                else -> fail }
33    
34        Directory<ShaderFile, Shader>.create directory_path
35                                             { shader/file/get _ _ }
36                                             { g _ }
37    
38    let get_image_directory (directory_path : String) =
39        let g (path_memory : obs/Map<String, ImageMemory>) =
40            let path_images = obs/Map.new
41    
42            let token = path_memory.bind
43                { path memory ->
44                      let image = Image.from_memory path memory
45                      path_images.add path image }
46    
47                { path prev_memory memory ->
48                      let prev_image = path_images[path]
49    
50                      if memory.width == prev_memory.width
51                         && memory.height == prev_memory.height
52                         && memory.format == prev_memory.format
53                      then
54                          prev_image.update memory.bytes.as_slice
55                      else
56                          let image = Image.from_memory path memory
57                          path_images.add path image
58                          prev_image.discard }
59    
60                { path _ ->
61                      let image = path_images[path]
62                      path_images.remove path
63                      image.discard }
64    
65            path_images.push_token token
66    
67            path_images.as_readonly
68    
69        Directory<ImageMemory, Image>.create directory_path { ImageMemory.load _ } { g _ }
70    
71    let get_mesh_directory (directory_path : String) : Directory<MeshFile, Mesh> =
72        let get_name (id : String) =
73            let items = id.split ' '
74            items[1]
75    
76        let g (id_files : obs/Map<String, MeshFile>) =
77            let id_meshes = obs/Map.new
78            let id_atoms = Map<String, mut Atom<Option<MeshMemory>>>.new
79    
80            id_files.bind
81                { id file ->
82                      let memory = get_name id
83                          |> file.try_memory
84                          |> Atom<Option<MeshMemory>>
85    
86                      let mesh = Mesh.from_memory memory.as_readonly
87                      id_atoms.add id memory
88                      id_meshes.add id mesh }
89    
90                { id _ file ->
91                      get_name id |> file.try_memory |> id_atoms[id].set }
92    
93                { id _ ->
94                      let mesh = id_meshes[id]
95                      id_meshes.remove id
96                      id_atoms.remove id
97                      mesh.discard }
98    
99            id_meshes.as_readonly
100   
101       Directory<MeshFile, Mesh>.create directory_path { mesh/file/get _ _ } { g _ }
102   
103   let get_font_directory (directory_path : String) =
104       let g (path_files : obs/Map<String, FontFile>) =
105           path_files |> Obs.map { path file -> Font.create path file }
106   
107       Directory<FontFile, Font>.create directory_path { FontFile.load _ } { g _ }
108   
109   object Resources =
110       def create (instance : Instance
111                   command_buffer : CommandBuffer
112                   buffer_pool : BufferPool) =
113           let develop_path : String @auto
114           let crates_path : String @auto
115   
116           let data_path = "$develop_path/data"
117           let shader_path = "$data_path/shaders"
118           let shader_source_path = "$crates_path/renderer/shaders"
119   
120           shader/preprocess shader_path shader_source_path
121           let shader_directory = get_shader_directory shader_path
122           let get_shader : GetShader = { path -> shader_directory.get path }
123   
124           let image_directory = get_image_directory "$data_path/bitmaps"
125           let image_changed = image_directory.id_assets.to_stream
126           let get_image : GetImage = { path -> image_directory.atom path }
127   
128           let mesh_directory = get_mesh_directory "$data_path/meshes"
129           let get_mesh : GetMesh = { id -> mesh_directory.get id }
130   
131           let font_directory = get_font_directory "$data_path/fonts"
132           let get_font : GetFont = { path -> font_directory.get path }
133   
134           Resources
135               =command_buffer
136               =buffer_pool
137               =get_image
138               =get_font
139               =get_mesh
140               =get_shader
141               =shader_path
142               =shader_source_path
143               =shader_directory
144               =image_directory
145               =mesh_directory
146               =font_directory
147               =image_changed
148   
149   type Resources
150       def update_all =
151           shader/preprocess shader_path shader_source_path
152           shader_directory.update_all
153           image_directory.update_all
154           mesh_directory.update_all
155           font_directory.update_all
156