1
+ use std:: future:: Future ;
1
2
use std:: sync:: { Arc , Mutex } ;
2
3
use std:: sync:: atomic:: AtomicUsize ;
3
4
use serde:: { Deserialize , Serialize } ;
4
5
use versions:: Version ;
5
6
use crate :: AppState ;
6
7
use crate :: downloads:: progress:: ProgressChecker ;
7
8
8
- #[ derive( Serialize , Deserialize , Clone ) ]
9
+ #[ derive( Serialize , Deserialize ) ]
9
10
#[ serde( rename_all="camelCase" ) ]
10
11
pub struct GameDownload {
11
12
id : String ,
12
13
version : Version ,
13
- progress : GameDownloadState
14
+ progress : Arc < AtomicUsize > ,
15
+ state : Mutex < GameDownloadState > ,
16
+ manifest : Option < Mutex < GameDownloadManifest > >
14
17
}
15
- #[ derive( Serialize , Deserialize , Clone ) ]
18
+ #[ derive( Serialize , Deserialize , Clone , Eq , PartialEq ) ]
16
19
pub enum GameDownloadState {
17
20
Uninitialised ,
21
+ Queued ,
18
22
Manifest ,
19
- Downloading ( Arc < AtomicUsize > ) ,
23
+ Downloading ,
20
24
Finished ,
21
25
Stalled ,
22
26
Failed ,
23
27
Cancelled
24
28
}
25
29
26
- #[ derive( Serialize , Deserialize , Clone ) ]
30
+ #[ derive( Serialize , Deserialize , Clone , Eq , PartialEq ) ]
27
31
pub enum GameDownloadError {
28
-
32
+ ManifestAlreadyExists ,
33
+ ManifestDoesNotExist ,
34
+ ManifestDownloadError ,
29
35
}
30
- #[ derive( Serialize , Deserialize ) ]
36
+ #[ derive( Serialize , Deserialize , Clone , Eq , PartialEq , Ord , PartialOrd ) ]
31
37
#[ serde( rename_all="camelCase" ) ]
32
38
pub struct GameChunkCtx {
33
39
chunk_id : usize ,
34
40
}
35
41
36
- #[ derive( Serialize , Deserialize , Clone ) ]
42
+ #[ derive( Serialize , Deserialize , Clone , Eq , PartialEq ) ]
37
43
pub struct GameDownloadManifest {
38
44
// TODO: Implement game manifest
39
45
}
@@ -43,17 +49,38 @@ impl GameDownload {
43
49
Self {
44
50
id,
45
51
version,
46
- progress : GameDownloadState :: Uninitialised
52
+ progress : Arc :: new ( AtomicUsize :: new ( 0 ) ) ,
53
+ state : Mutex :: from ( GameDownloadState :: Uninitialised ) ,
54
+ manifest : None
55
+ }
56
+ }
57
+ pub async fn queue ( & self ) -> Result < ( ) , GameDownloadError > {
58
+ self . change_state ( GameDownloadState :: Queued ) ;
59
+ if self . manifest . is_none ( ) {
60
+ return Ok ( ( ) )
47
61
}
62
+ self . download_manifest ( ) . await
48
63
}
49
- pub async fn download ( & mut self , max_threads : usize , contexts : Vec < GameChunkCtx > ) -> Result < ( ) , GameDownloadError > {
64
+ pub async fn download ( & self , max_threads : usize , contexts : Vec < GameChunkCtx > ) -> Result < ( ) , GameDownloadError > {
50
65
let progress = Arc :: new ( AtomicUsize :: new ( 0 ) ) ;
51
- self . progress = GameDownloadState :: Downloading ( progress . clone ( ) ) ;
66
+ self . change_state ( GameDownloadState :: Downloading ) ;
52
67
let progress = ProgressChecker :: new ( Box :: new ( download_game_chunk) , progress) ;
53
68
progress. run_contexts_parallel_async ( contexts, max_threads) . await ;
54
69
Ok ( ( ) )
55
70
}
56
- pub async fn download_manifest ( & mut self ) -> Result < GameDownloadManifest , GameDownloadError > {
71
+ pub async fn download_manifest ( & self ) -> Result < ( ) , GameDownloadError > {
72
+ if self . manifest . is_some ( ) {
73
+ return Err ( GameDownloadError :: ManifestAlreadyExists ) ;
74
+ }
75
+ todo ! ( ) // Need to actually download the manifest
76
+ }
77
+ pub fn change_state ( & self , state : GameDownloadState ) {
78
+ let mut lock = self . state . lock ( ) . unwrap ( ) ;
79
+ * lock = state;
80
+ }
81
+ }
82
+ impl GameDownloadManifest {
83
+ fn parse_to_chunks ( & self ) -> Vec < GameChunkCtx > {
57
84
todo ! ( )
58
85
}
59
86
}
@@ -71,18 +98,26 @@ pub async fn start_game_download(
71
98
) -> Result < ( ) , GameDownloadError > {
72
99
let mut download = Arc :: new ( GameDownload :: new ( game_id, game_version) ) ;
73
100
let mut app_state = state. lock ( ) . unwrap ( ) ;
74
- app_state. game_downloads . push ( download. clone ( ) ) ;
75
101
76
- let manifest = match download. download_manifest ( ) . await {
77
- Ok ( manifest) => { manifest }
78
- Err ( e) => { return Err ( e) }
102
+ let tmp = download. clone ( ) ;
103
+ let manifest = & tmp. manifest ;
104
+
105
+ let Some ( unlocked) = manifest else { return Err ( GameDownloadError :: ManifestDoesNotExist ) } ;
106
+ let lock = unlocked. lock ( ) . unwrap ( ) ;
107
+
108
+ let chunks = lock. parse_to_chunks ( ) ;
109
+
110
+ /*
111
+ let manifest = match d.manifest {
112
+ Some(lock) => {
113
+ let lock = lock.lock().unwrap();
114
+ lock.parse_to_chunks()
115
+ },
116
+ None => { return Err(GameDownloadError::ManifestDoesNotExist) }
79
117
};
118
+ */
80
119
81
- download. download ( max_threads, manifest. parse_to_chunks ( ) ) . await
120
+ app_state. game_downloads . push ( download. clone ( ) ) ;
121
+ download. download ( max_threads, chunks) . await
82
122
}
83
123
84
- impl GameDownloadManifest {
85
- fn parse_to_chunks ( self ) -> Vec < GameChunkCtx > {
86
- todo ! ( )
87
- }
88
- }
0 commit comments