1use std::collections::HashMap;
2struct AsyncFile(String, uni_app::fs::File, Option<Vec<u8>>);
3
4#[derive(Default)]
5pub struct FileLoader {
7 files_to_load: HashMap<usize, AsyncFile>,
8 seq: usize,
9}
10
11impl FileLoader {
12 pub fn new() -> Self {
13 Default::default()
14 }
15 pub fn load_file(&mut self, path: &str) -> Result<usize, String> {
17 uni_app::App::print(format!("loading file {}\n", path));
18 match open_file(path) {
19 Ok(mut f) => {
20 if f.is_ready() {
21 match f.read_binary() {
22 Ok(buf) => {
23 self.files_to_load
24 .insert(self.seq, AsyncFile(path.to_owned(), f, Some(buf)));
25 self.seq += 1;
26 Ok(self.seq - 1)
27 }
28 Err(e) => Err(format!("Could not read file {} : {}\n", path, e)),
29 }
30 } else {
31 uni_app::App::print(format!("loading async file {}\n", path));
32 self.files_to_load
33 .insert(self.seq, AsyncFile(path.to_owned(), f, None));
34 self.seq += 1;
35 Ok(self.seq - 1)
36 }
37 }
38 Err(e) => Err(format!("Could not open file {} : {}\n", path, e)),
39 }
40 }
41
42 fn load_file_async(&mut self) -> bool {
43 for (_, f) in self.files_to_load.iter_mut() {
44 if f.1.is_ready() && f.2.is_none() {
45 match f.1.read_binary() {
46 Ok(buf) => {
47 f.2 = Some(buf);
48 }
49 Err(e) => panic!("could not load async file {} : {}", f.0, e),
50 }
51 }
52 }
53 true
54 }
55
56 pub fn check_file_ready(&mut self, id: usize) -> bool {
58 self.load_file_async();
59 if let Some(f) = self.files_to_load.get(&id) {
60 return f.2.is_some();
61 }
62 false
63 }
64
65 pub fn get_file_content(&mut self, id: usize) -> Vec<u8> {
67 let mut f = self.files_to_load.remove(&id).unwrap();
68 f.2.take().unwrap()
69 }
70}
71
72fn open_file(filename: &str) -> Result<uni_app::fs::File, std::io::Error> {
73 let ffilename =
74 if cfg!(not(target_arch = "wasm32")) && &filename[0..1] != "/" && &filename[1..2] != ":" {
75 "www/".to_owned() + filename
76 } else {
77 filename.to_owned()
78 };
79 uni_app::fs::FileSystem::open(&ffilename)
80}