@@ -8,42 +8,55 @@ namespace TaloGameServices
88{
99 public class SavesAPI : BaseAPI
1010 {
11- private GameSave _currentSave ;
12- internal List < GameSave > _allSaves = new ( ) ;
13- internal List < LoadableData > _registeredLoadables = new ( ) ;
14- private List < string > _loadedLoadables = new ( ) ;
11+ internal SavesManager savesManager ;
12+ internal SavesContentManager contentManager ;
1513
1614 public event Action OnSavesLoaded ;
17- public event Action < GameSave > OnSaveChosen ;
1815 public event Action OnSaveLoadingCompleted ;
1916
20- private IFileHandler < OfflineSavesContent > _fileHandler ;
17+ public event Action < GameSave > OnSaveChosen ;
18+ public event Action < GameSave > OnSaveUnloaded ;
2119
2220 public GameSave [ ] All
2321 {
24- get => _allSaves . ToArray ( ) ;
22+ get => savesManager . AllSaves ;
2523 }
2624
2725 public GameSave Latest
2826 {
29- get {
30- if ( _allSaves . Count == 0 ) return null ;
31- return _allSaves . OrderByDescending ( ( save ) => DateTime . Parse ( save . updatedAt ) ) . First ( ) ;
32- }
27+ get => savesManager . GetLatestSave ( ) ;
3328 }
3429
3530 public GameSave Current
3631 {
37- get => _currentSave ;
32+ get => savesManager . CurrentSave ;
3833 }
3934
40- public SavesAPI ( ) : base ( "v1/game-saves" ) {
41- _fileHandler = Talo . TestMode
42- ? new SavesTestFileHandler ( )
43- : new SavesFileHandler ( ) ;
35+ public SavesAPI ( ) : base ( "v1/game-saves" )
36+ { }
37+
38+ internal void Setup ( )
39+ {
40+ savesManager = new ( ) ;
41+ contentManager = new ( ) ;
42+
43+ savesManager . OnSaveChosen += ( save ) =>
44+ {
45+ OnSaveChosen ? . Invoke ( save ) ;
46+ } ;
47+
48+ savesManager . OnSavesLoaded += ( ) =>
49+ {
50+ OnSavesLoaded ? . Invoke ( ) ;
51+ } ;
52+
53+ contentManager . OnSaveLoadingCompleted += ( ) =>
54+ {
55+ OnSaveLoadingCompleted ? . Invoke ( ) ;
56+ } ;
4457 }
4558
46- private async Task < GameSave > ReplaceSaveWithOfflineSave ( GameSave offlineSave )
59+ public async Task < GameSave > ReplaceSaveWithOfflineSave ( GameSave offlineSave )
4760 {
4861 var uri = new Uri ( $ "{ baseUrl } /{ offlineSave . id } ") ;
4962 var json = await Call ( uri , "PATCH" , JsonUtility . ToJson ( new SavesPatchRequest
@@ -56,43 +69,10 @@ private async Task<GameSave> ReplaceSaveWithOfflineSave(GameSave offlineSave)
5669 return res . save ;
5770 }
5871
59- private async Task < GameSave > SyncSave ( GameSave onlineSave , GameSave offlineSave )
60- {
61- var onlineUpdatedAt = DateTime . Parse ( onlineSave . updatedAt ) ;
62- var offlineUpdatedAt = DateTime . Parse ( offlineSave . updatedAt ) ;
63-
64- if ( DateTime . Compare ( offlineUpdatedAt , onlineUpdatedAt ) > 0 )
65- {
66- var save = await ReplaceSaveWithOfflineSave ( offlineSave ) ;
67- return save ;
68- }
69- else
70- {
71- return onlineSave ;
72- }
73- }
74-
75- private async Task < GameSave [ ] > SyncOfflineSaves ( GameSave [ ] offlineSaves )
76- {
77- var newSaves = new List < GameSave > ( ) ;
78-
79- foreach ( var offlineSave in offlineSaves )
80- {
81- if ( offlineSave . id < 0 )
82- {
83- var save = await CreateSave ( offlineSave . name , offlineSave . content ) ;
84- DeleteOfflineSave ( offlineSave . id ) ;
85- newSaves . Add ( save ) ;
86- }
87- }
88-
89- return newSaves . ToArray ( ) ;
90- }
91-
9272 public async Task < GameSave [ ] > GetSaves ( )
9373 {
9474 var saves = new List < GameSave > ( ) ;
95- var offlineSaves = GetOfflineSavesContent ( ) ? . saves ;
75+ var offlineSaves = savesManager . GetOfflineSavesContent ( ) ? . saves ;
9676
9777 if ( Talo . IsOffline ( ) )
9878 {
@@ -108,120 +88,42 @@ public async Task<GameSave[]> GetSaves()
10888 var onlineSaves = res . saves ;
10989
11090 if ( offlineSaves != null )
111- {
112- var tasks = onlineSaves . Select ( async ( onlineSave ) =>
11391 {
114- var offlineSave = offlineSaves
115- . FirstOrDefault ( ( offlineSave ) => offlineSave . id == onlineSave . id ) ;
116-
117- if ( offlineSave != null )
92+ var tasks = onlineSaves . Select ( async ( onlineSave ) =>
11893 {
119- return await SyncSave ( onlineSave , offlineSave ) ;
120- }
121- return onlineSave ;
122- } )
123- . ToList ( ) ;
94+ var offlineSave = offlineSaves
95+ . FirstOrDefault ( ( offlineSave ) => offlineSave . id == onlineSave . id ) ;
12496
125- onlineSaves = await Task . WhenAll ( tasks ) ;
97+ if ( offlineSave != null )
98+ {
99+ return await savesManager . SyncSave ( onlineSave , offlineSave ) ;
100+ }
101+ return onlineSave ;
102+ } )
103+ . ToList ( ) ;
126104
127- var syncedSaves = await SyncOfflineSaves ( offlineSaves ) ;
128- saves . AddRange ( syncedSaves ) ;
129- }
105+ onlineSaves = await Task . WhenAll ( tasks ) ;
130106
131- saves . AddRange ( onlineSaves ) ;
132- }
133-
134- _allSaves = saves ;
135- OnSavesLoaded ? . Invoke ( ) ;
107+ var syncedSaves = await savesManager . SyncOfflineSaves ( offlineSaves ) ;
108+ saves . AddRange ( syncedSaves ) ;
109+ }
136110
137- foreach ( var save in _allSaves )
138- {
139- UpdateOfflineSaves ( save ) ;
111+ saves . AddRange ( onlineSaves ) ;
140112 }
141113
142- return _allSaves . ToArray ( ) ;
114+ savesManager . HandleSavesLoaded ( saves ) ;
115+ return savesManager . AllSaves ;
143116 }
144117
145118 public void Register ( Loadable loadable )
146119 {
147- _registeredLoadables . Add ( new LoadableData ( loadable ) ) ;
148- }
149-
150- internal string GetOfflineSavesPath ( )
151- {
152- return Application . persistentDataPath + $ "/ts.{ Talo . CurrentPlayer . id } .bin";
153- }
154-
155- internal OfflineSavesContent GetOfflineSavesContent ( )
156- {
157- return _fileHandler . ReadContent ( GetOfflineSavesPath ( ) ) ;
158- }
159-
160- internal void WriteOfflineSavesContent ( OfflineSavesContent newContent )
161- {
162- _fileHandler . WriteContent ( GetOfflineSavesPath ( ) , newContent ) ;
163- }
164-
165- private GameSave CreateOfflineCopy ( GameSave originalSave )
166- {
167- return new GameSave
168- {
169- id = originalSave . id ,
170- name = originalSave . name ,
171- content = originalSave . content ,
172- updatedAt = originalSave . updatedAt
173- } ;
174- }
175-
176- private GameSave UpdateOfflineSaves ( GameSave incomingSave )
177- {
178- var offlineIncomingSave = CreateOfflineCopy ( incomingSave ) ;
179- var offlineContent = GetOfflineSavesContent ( ) ;
180- var updated = false ;
181-
182- if ( offlineContent ? . saves != null )
183- {
184- // updating
185- offlineContent . saves = offlineContent . saves . Select ( ( existingSave ) =>
186- {
187- if ( existingSave . id == offlineIncomingSave . id )
188- {
189- updated = true ;
190- return offlineIncomingSave ;
191- }
192- return existingSave ;
193- } ) . ToArray ( ) ;
194-
195- // appending
196- if ( ! updated )
197- {
198- if ( offlineIncomingSave . id == 0 )
199- {
200- offlineIncomingSave . id = - offlineContent . saves . Length - 1 ;
201- }
202-
203- offlineContent . saves = offlineContent . saves . Concat ( new GameSave [ ] { offlineIncomingSave } ) . ToArray ( ) ;
204- }
205- }
206- else
207- {
208- // first entry into the saves file
209- if ( offlineIncomingSave . id == 0 )
210- {
211- offlineIncomingSave . id = - 1 ;
212- }
213- offlineContent = new OfflineSavesContent ( new GameSave [ ] { offlineIncomingSave } ) ;
214- }
215-
216- WriteOfflineSavesContent ( offlineContent ) ;
217- return offlineIncomingSave ;
120+ contentManager . Register ( loadable ) ;
218121 }
219122
220- public async Task < GameSave > CreateSave ( string saveName , string content = null )
123+ public async Task < GameSave > CreateSave ( string saveName , SaveContent content = null )
221124 {
222125 GameSave save ;
223-
224- string saveContent = content ?? JsonUtility . ToJson ( new SaveContent ( _registeredLoadables ) ) ;
126+ var saveContent = content ?? contentManager . Content ;
225127
226128 if ( Talo . IsOffline ( ) )
227129 {
@@ -247,33 +149,19 @@ public async Task<GameSave> CreateSave(string saveName, string content = null)
247149 save = res . save ;
248150 }
249151
250- _allSaves . Add ( save ) ;
251-
252- var offlineSave = UpdateOfflineSaves ( save ) ;
253- var chosenSave = Talo . IsOffline ( ) ? offlineSave : save ;
254-
255- SetChosenSave ( chosenSave , false ) ;
256- return chosenSave ;
152+ return savesManager . CreateSave ( save ) ;
257153 }
258154
259155 public async Task < GameSave > UpdateCurrentSave ( string newName = "" )
260156 {
261- return await UpdateSave ( _currentSave . id , newName ) ;
262- }
263-
264- private GameSave FindSaveByID ( int saveId )
265- {
266- GameSave save = _allSaves . FirstOrDefault ( ( existingSave ) => existingSave . id == saveId ) ;
267- if ( save == null ) throw new Exception ( "Save not found" ) ;
268-
269- return save ;
157+ return await UpdateSave ( savesManager . CurrentSave . id , newName ) ;
270158 }
271159
272160 public async Task < GameSave > UpdateSave ( int saveId , string newName = "" )
273161 {
274- var save = FindSaveByID ( saveId ) ;
162+ var save = savesManager . FindSaveByID ( saveId ) ;
275163
276- var saveContent = JsonUtility . ToJson ( new SaveContent ( _registeredLoadables ) ) ;
164+ var saveContent = contentManager . Content ;
277165
278166 if ( Talo . IsOffline ( ) )
279167 {
@@ -298,53 +186,30 @@ public async Task<GameSave> UpdateSave(int saveId, string newName = "")
298186 save = res . save ;
299187 }
300188
301- _allSaves = _allSaves
302- . Select ( ( existingSave ) => existingSave . id == saveId ? save : existingSave )
303- . ToList ( ) ;
304- UpdateOfflineSaves ( save ) ;
189+ savesManager . HandleSaveUpdated ( save ) ;
305190
306191 return save ;
307192 }
308193
309- private void SetChosenSave ( GameSave save , bool loadSave = true )
194+ public void ChooseSave ( int saveId , bool loadSave = true )
310195 {
311- _currentSave = save ;
312- if ( ! loadSave ) return ;
313-
314- _loadedLoadables . Clear ( ) ;
315- OnSaveChosen ? . Invoke ( save ) ;
316- }
317-
318- public void ChooseSave ( int saveId )
319- {
320- var save = FindSaveByID ( saveId ) ;
321- SetChosenSave ( save ) ;
196+ var save = savesManager . FindSaveByID ( saveId ) ;
197+ savesManager . SetChosenSave ( save , loadSave ) ;
322198 }
323199
324200 public void UnloadCurrentSave ( )
325201 {
326- SetChosenSave ( null ) ;
327- }
328-
329- public void SetObjectLoaded ( string id )
330- {
331- _loadedLoadables . Add ( id ) ;
332- if ( _loadedLoadables . Count == _registeredLoadables . Count )
202+ if ( Current != null )
333203 {
334- OnSaveLoadingCompleted ? . Invoke ( ) ;
204+ OnSaveUnloaded ? . Invoke ( Current ) ;
335205 }
336- }
337206
338- private void DeleteOfflineSave ( int saveId )
339- {
340- var offlineContent = GetOfflineSavesContent ( ) ;
341- offlineContent . saves = offlineContent . saves . Where ( ( save ) => save . id != saveId ) . ToArray ( ) ;
342- WriteOfflineSavesContent ( offlineContent ) ;
207+ savesManager . UnloadCurrentSave ( ) ;
343208 }
344209
345210 public async Task DeleteSave ( int saveId )
346211 {
347- var save = FindSaveByID ( saveId ) ;
212+ var save = savesManager . FindSaveByID ( saveId ) ;
348213
349214 if ( ! Talo . IsOffline ( ) )
350215 {
@@ -353,13 +218,7 @@ public async Task DeleteSave(int saveId)
353218 await Call ( uri , "DELETE" ) ;
354219 }
355220
356- _allSaves = _allSaves . Where ( ( existingSave ) => existingSave . id != saveId ) . ToList ( ) ;
357- DeleteOfflineSave ( saveId ) ;
358-
359- if ( _currentSave ? . id == saveId )
360- {
361- UnloadCurrentSave ( ) ;
362- }
221+ savesManager . DeleteSave ( saveId ) ;
363222 }
364223 }
365224}
0 commit comments