Skip to content

Commit eea8090

Browse files
committed
Steam storage improvements
* Implemented EnumerateStorageDirectory() * Implemented RemoveStoragePath() * Fixed init failure if the application previously crashed with a write batch in progress * Allow creation of multiple Steam storage objects, the write batch is complete when the last storage is closed * Check to see if a file exists in GetStoragePathInfo()
1 parent 96b5c92 commit eea8090

File tree

2 files changed

+102
-9
lines changed

2 files changed

+102
-9
lines changed

src/storage/steam/SDL_steamstorage.c

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
5860
static 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+
78144
static 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+
132217
static 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

212299
steamfail:

src/storage/steam/SDL_steamstorage_proc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,15 @@ STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp, (void*))
66
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch, (void*))
77
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_EndFileWriteBatch, (void*))
88

9+
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_FileExists, (void*, const char*))
910
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_GetFileSize, (void*, const char*))
11+
STEAM_PROC(Sint64, SteamAPI_ISteamRemoteStorage_GetFileTimestamp, (void*, const char *))
1012
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileRead, (void*, const char*, void*, Sint32))
1113
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileWrite, (void*, const char*, const void*, Sint32))
14+
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_FileDelete, (void*, const char*))
1215
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_GetQuota, (void*, Uint64*, Uint64*))
1316

17+
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_GetFileCount, (void*))
18+
STEAM_PROC(const char *, SteamAPI_ISteamRemoteStorage_GetFileNameAndSize, (void*, int, Sint32*))
19+
1420
#undef STEAM_PROC

0 commit comments

Comments
 (0)