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