@@ -55,15 +55,20 @@ typedef struct STEAM_RemoteStorage
5555 #include "SDL_steamstorage_proc.h"
5656} STEAM_RemoteStorage ;
5757
58+ static SDL_AtomicInt SDL_steam_storage_refcount ;
59+
5860static bool STEAM_CloseStorage (void * userdata )
5961{
6062 bool result = true;
6163 STEAM_RemoteStorage * steam = (STEAM_RemoteStorage * )userdata ;
6264 void * steamremotestorage = steam -> SteamAPI_SteamRemoteStorage_v016 ();
65+ bool end_batch = SDL_AtomicDecRef (& SDL_steam_storage_refcount );
6366 if (steamremotestorage == NULL ) {
6467 result = SDL_SetError ("SteamRemoteStorage unavailable" );
65- } else if (!steam -> SteamAPI_ISteamRemoteStorage_EndFileWriteBatch (steamremotestorage )) {
66- result = SDL_SetError ("SteamRemoteStorage()->EndFileWriteBatch() failed" );
68+ } else if (end_batch ) {
69+ if (!steam -> SteamAPI_ISteamRemoteStorage_EndFileWriteBatch (steamremotestorage )) {
70+ result = SDL_SetError ("SteamRemoteStorage()->EndFileWriteBatch() failed" );
71+ }
6772 }
6873 SDL_UnloadObject (steam -> libsteam_api );
6974 SDL_free (steam );
@@ -75,6 +80,67 @@ static bool STEAM_StorageReady(void *userdata)
7580 return true;
7681}
7782
83+ static bool STEAM_EnumerateStorageDirectory (void * userdata , const char * path , SDL_EnumerateDirectoryCallback callback , void * callback_userdata )
84+ {
85+ bool result = true;
86+ STEAM_RemoteStorage * steam = (STEAM_RemoteStorage * )userdata ;
87+ void * steamremotestorage = steam -> SteamAPI_SteamRemoteStorage_v016 ();
88+ if (steamremotestorage == NULL ) {
89+ return SDL_SetError ("SteamRemoteStorage unavailable" );
90+ }
91+
92+ const char * prefix ;
93+ if (SDL_strcmp (path , "." ) == 0 ) {
94+ prefix = "" ;
95+ } else {
96+ prefix = path ;
97+ while (* prefix == '/' ) {
98+ ++ prefix ;
99+ }
100+ }
101+ size_t prefixlen = SDL_strlen (prefix );
102+ while (prefixlen > 0 && prefix [prefixlen - 1 ] == '/' ) {
103+ -- prefixlen ;
104+ }
105+
106+ bool done = false;
107+ Sint32 count = steam -> SteamAPI_ISteamRemoteStorage_GetFileCount (steamremotestorage );
108+ for (Sint32 i = 0 ; i < count && !done ; ++ i ) {
109+ const char * file = steam -> SteamAPI_ISteamRemoteStorage_GetFileNameAndSize (steamremotestorage , i , NULL );
110+ if (!file ) {
111+ continue ;
112+ }
113+
114+ const char * fname ;
115+ if (prefixlen > 0 ) {
116+ // Make sure the prefix matches
117+ if (SDL_strncmp (prefix , file , prefixlen ) != 0 || * (file + prefixlen ) != '/' ) {
118+ continue ;
119+ }
120+ fname = file + prefixlen + 1 ;
121+ } else {
122+ // Make sure this is a top-level file
123+ if (SDL_strchr (file , '/' ) != NULL ) {
124+ continue ;
125+ }
126+ fname = file ;
127+ }
128+
129+ switch (callback (callback_userdata , path , fname )) {
130+ case SDL_ENUM_SUCCESS :
131+ done = true;
132+ break ;
133+ case SDL_ENUM_FAILURE :
134+ result = false;
135+ done = true;
136+ break ;
137+ default :
138+ break ;
139+ }
140+ }
141+ return result ;
142+ }
143+
78144static bool STEAM_GetStoragePathInfo (void * userdata , const char * path , SDL_PathInfo * info )
79145{
80146 STEAM_RemoteStorage * steam = (STEAM_RemoteStorage * )userdata ;
@@ -83,10 +149,16 @@ static bool STEAM_GetStoragePathInfo(void *userdata, const char *path, SDL_PathI
83149 return SDL_SetError ("SteamRemoteStorage unavailable" );
84150 }
85151
152+ if (!steam -> SteamAPI_ISteamRemoteStorage_FileExists (steamremotestorage , path )) {
153+ return SDL_SetError ("Can't stat" );
154+ }
155+
86156 if (info ) {
87157 SDL_zerop (info );
88158 info -> type = SDL_PATHTYPE_FILE ;
89159 info -> size = steam -> SteamAPI_ISteamRemoteStorage_GetFileSize (steamremotestorage , path );
160+ Sint64 mtime = steam -> SteamAPI_ISteamRemoteStorage_GetFileTimestamp (steamremotestorage , path );
161+ info -> modify_time = (SDL_Time )SDL_SECONDS_TO_NS (mtime );
90162 }
91163 return true;
92164}
@@ -129,6 +201,19 @@ static bool STEAM_WriteStorageFile(void *userdata, const char *path, const void
129201 return result ;
130202}
131203
204+ static bool STEAM_RemoveStoragePath (void * userdata , const char * path )
205+ {
206+ STEAM_RemoteStorage * steam = (STEAM_RemoteStorage * )userdata ;
207+ void * steamremotestorage = steam -> SteamAPI_SteamRemoteStorage_v016 ();
208+ if (steamremotestorage == NULL ) {
209+ return SDL_SetError ("SteamRemoteStorage unavailable" );
210+ }
211+ if (!steam -> SteamAPI_ISteamRemoteStorage_FileDelete (steamremotestorage , path )) {
212+ return SDL_SetError ("SteamRemoteStorage()->FileDelete() failed" );
213+ }
214+ return true;
215+ }
216+
132217static Uint64 STEAM_GetStorageSpaceRemaining (void * userdata )
133218{
134219 Uint64 total , remaining ;
@@ -149,12 +234,12 @@ static const SDL_StorageInterface STEAM_user_iface = {
149234 sizeof (SDL_StorageInterface ),
150235 STEAM_CloseStorage ,
151236 STEAM_StorageReady ,
152- NULL , // enumerate
237+ STEAM_EnumerateStorageDirectory ,
153238 STEAM_GetStoragePathInfo ,
154239 STEAM_ReadStorageFile ,
155240 STEAM_WriteStorageFile ,
156241 NULL , // mkdir
157- NULL , // remove
242+ STEAM_RemoveStoragePath ,
158243 NULL , // rename
159244 NULL , // copy
160245 STEAM_GetStorageSpaceRemaining
@@ -198,15 +283,17 @@ static SDL_Storage *STEAM_User_Create(const char *org, const char *app, SDL_Prop
198283 SDL_SetError ("Steam cloud is disabled for this application" );
199284 goto steamfail ;
200285 }
201- if (!steam -> SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch (steamremotestorage )) {
202- SDL_SetError ("SteamRemoteStorage()->BeginFileWriteBatch() failed" );
203- goto steamfail ;
204- }
205286
206287 result = SDL_OpenStorage (& STEAM_user_iface , steam );
207- if (result == NULL ) {
288+ if (! result ) {
208289 goto steamfail ;
209290 }
291+
292+ if (SDL_AtomicIncRef (& SDL_steam_storage_refcount ) == 0 ) {
293+ if (!steam -> SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch (steamremotestorage )) {
294+ // We probably already have a batch in progress (maybe we crashed earlier?)
295+ }
296+ }
210297 return result ;
211298
212299steamfail :
0 commit comments