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 70 { ImageMemory.load _ } 71 { g _ } 72 73 let get_mesh_directory (directory_path : String) : Directory<MeshFile, Mesh> = 74 let get_name (id : String) = 75 let items = id.split ' ' 76 items[1] 77 78 let g (id_files : obs/Map<String, MeshFile>) = 79 let id_meshes = obs/Map.new 80 let id_atoms = Map<String, mut Atom<Option<MeshMemory>>>.new 81 82 id_files.bind 83 { id file -> 84 let memory = get_name id 85 |> file.try_memory 86 |> Atom<Option<MeshMemory>> 87 88 let mesh = Mesh.from_memory memory.as_readonly 89 id_atoms.add id memory 90 id_meshes.add id mesh } 91 92 { id _ file -> 93 get_name id |> file.try_memory |> id_atoms[id].set } 94 95 { id _ -> 96 let mesh = id_meshes[id] 97 id_meshes.remove id 98 id_atoms.remove id 99 mesh.discard } 100 101 id_meshes.as_readonly 102 103 Directory<MeshFile, Mesh>.create directory_path { mesh/file/get _ _ } { g _ } 104 105 let get_font_directory (directory_path : String) = 106 let g (path_files : obs/Map<String, FontFile>) = 107 path_files |> Obs.map { path file -> Font.create path file } 108 109 Directory<FontFile, Font>.create directory_path { FontFile.load _ } { g _ } 110 111 object Resources = 112 def create (instance : Instance 113 command_buffer : CommandBuffer 114 buffer_pool : BufferPool) = 115 let develop_path : String @auto 116 let crates_path : String @auto 117 118 let data_path = "$develop_path/data" 119 let shader_path = "$data_path/shaders" 120 let shader_source_path = "$crates_path/renderer/shaders" 121 122 shader/preprocess shader_path shader_source_path 123 let shader_directory = get_shader_directory shader_path 124 let get_shader : GetShader = { path -> shader_directory.get path } 125 126 let image_directory = get_image_directory "$data_path/bitmaps" 127 let image_changed = image_directory.id_assets.to_stream 128 let get_image : GetImage = { path -> image_directory.get_atom path } 129 130 let mesh_directory = get_mesh_directory "$data_path/meshes" 131 let get_mesh : GetMesh = { id -> mesh_directory.get id } 132 133 let font_directory = get_font_directory "$data_path/fonts" 134 let get_font : GetFont = { path -> font_directory.get path } 135 136 Resources 137 =command_buffer 138 =buffer_pool 139 =get_image 140 =get_font 141 =get_mesh 142 =get_shader 143 =shader_path 144 =shader_source_path 145 =shader_directory 146 =image_directory 147 =mesh_directory 148 =font_directory 149 =image_changed 150 151 type Resources 152 def update_all = 153 shader/preprocess shader_path shader_source_path 154 shader_directory.update_all 155 image_directory.update_all 156 mesh_directory.update_all 157 font_directory.update_all 158