mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-01-07 22:03:20 +00:00
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()
This commit is contained in:
@@ -55,15 +55,20 @@ typedef struct STEAM_RemoteStorage
|
||||
#include "SDL_steamstorage_proc.h"
|
||||
} STEAM_RemoteStorage;
|
||||
|
||||
static SDL_AtomicInt SDL_steam_storage_refcount;
|
||||
|
||||
static bool STEAM_CloseStorage(void *userdata)
|
||||
{
|
||||
bool result = true;
|
||||
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
|
||||
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
|
||||
bool end_batch = SDL_AtomicDecRef(&SDL_steam_storage_refcount);
|
||||
if (steamremotestorage == NULL) {
|
||||
result = SDL_SetError("SteamRemoteStorage unavailable");
|
||||
} else if (!steam->SteamAPI_ISteamRemoteStorage_EndFileWriteBatch(steamremotestorage)) {
|
||||
result = SDL_SetError("SteamRemoteStorage()->EndFileWriteBatch() failed");
|
||||
} else if (end_batch) {
|
||||
if (!steam->SteamAPI_ISteamRemoteStorage_EndFileWriteBatch(steamremotestorage)) {
|
||||
result = SDL_SetError("SteamRemoteStorage()->EndFileWriteBatch() failed");
|
||||
}
|
||||
}
|
||||
SDL_UnloadObject(steam->libsteam_api);
|
||||
SDL_free(steam);
|
||||
@@ -75,6 +80,67 @@ static bool STEAM_StorageReady(void *userdata)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool STEAM_EnumerateStorageDirectory(void *userdata, const char *path, SDL_EnumerateDirectoryCallback callback, void *callback_userdata)
|
||||
{
|
||||
bool result = true;
|
||||
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
|
||||
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
|
||||
if (steamremotestorage == NULL) {
|
||||
return SDL_SetError("SteamRemoteStorage unavailable");
|
||||
}
|
||||
|
||||
const char *prefix;
|
||||
if (SDL_strcmp(path, ".") == 0) {
|
||||
prefix = "";
|
||||
} else {
|
||||
prefix = path;
|
||||
while (*prefix == '/') {
|
||||
++prefix;
|
||||
}
|
||||
}
|
||||
size_t prefixlen = SDL_strlen(prefix);
|
||||
while (prefixlen > 0 && prefix[prefixlen - 1] == '/') {
|
||||
--prefixlen;
|
||||
}
|
||||
|
||||
bool done = false;
|
||||
Sint32 count = steam->SteamAPI_ISteamRemoteStorage_GetFileCount(steamremotestorage);
|
||||
for (Sint32 i = 0; i < count && !done; ++i) {
|
||||
const char *file = steam->SteamAPI_ISteamRemoteStorage_GetFileNameAndSize(steamremotestorage, i, NULL);
|
||||
if (!file) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *fname;
|
||||
if (prefixlen > 0) {
|
||||
// Make sure the prefix matches
|
||||
if (SDL_strncmp(prefix, file, prefixlen) != 0 || *(file + prefixlen) != '/') {
|
||||
continue;
|
||||
}
|
||||
fname = file + prefixlen + 1;
|
||||
} else {
|
||||
// Make sure this is a top-level file
|
||||
if (SDL_strchr(file, '/') != NULL) {
|
||||
continue;
|
||||
}
|
||||
fname = file;
|
||||
}
|
||||
|
||||
switch (callback(callback_userdata, path, fname)) {
|
||||
case SDL_ENUM_SUCCESS:
|
||||
done = true;
|
||||
break;
|
||||
case SDL_ENUM_FAILURE:
|
||||
result = false;
|
||||
done = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool STEAM_GetStoragePathInfo(void *userdata, const char *path, SDL_PathInfo *info)
|
||||
{
|
||||
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
|
||||
@@ -83,10 +149,16 @@ static bool STEAM_GetStoragePathInfo(void *userdata, const char *path, SDL_PathI
|
||||
return SDL_SetError("SteamRemoteStorage unavailable");
|
||||
}
|
||||
|
||||
if (!steam->SteamAPI_ISteamRemoteStorage_FileExists(steamremotestorage, path)) {
|
||||
return SDL_SetError("Can't stat");
|
||||
}
|
||||
|
||||
if (info) {
|
||||
SDL_zerop(info);
|
||||
info->type = SDL_PATHTYPE_FILE;
|
||||
info->size = steam->SteamAPI_ISteamRemoteStorage_GetFileSize(steamremotestorage, path);
|
||||
Sint64 mtime = steam->SteamAPI_ISteamRemoteStorage_GetFileTimestamp(steamremotestorage, path);
|
||||
info->modify_time = (SDL_Time)SDL_SECONDS_TO_NS(mtime);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -129,6 +201,19 @@ static bool STEAM_WriteStorageFile(void *userdata, const char *path, const void
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool STEAM_RemoveStoragePath(void *userdata, const char *path)
|
||||
{
|
||||
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
|
||||
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
|
||||
if (steamremotestorage == NULL) {
|
||||
return SDL_SetError("SteamRemoteStorage unavailable");
|
||||
}
|
||||
if (!steam->SteamAPI_ISteamRemoteStorage_FileDelete(steamremotestorage, path)) {
|
||||
return SDL_SetError("SteamRemoteStorage()->FileDelete() failed");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static Uint64 STEAM_GetStorageSpaceRemaining(void *userdata)
|
||||
{
|
||||
Uint64 total, remaining;
|
||||
@@ -149,12 +234,12 @@ static const SDL_StorageInterface STEAM_user_iface = {
|
||||
sizeof(SDL_StorageInterface),
|
||||
STEAM_CloseStorage,
|
||||
STEAM_StorageReady,
|
||||
NULL, // enumerate
|
||||
STEAM_EnumerateStorageDirectory,
|
||||
STEAM_GetStoragePathInfo,
|
||||
STEAM_ReadStorageFile,
|
||||
STEAM_WriteStorageFile,
|
||||
NULL, // mkdir
|
||||
NULL, // remove
|
||||
STEAM_RemoveStoragePath,
|
||||
NULL, // rename
|
||||
NULL, // copy
|
||||
STEAM_GetStorageSpaceRemaining
|
||||
@@ -198,14 +283,16 @@ static SDL_Storage *STEAM_User_Create(const char *org, const char *app, SDL_Prop
|
||||
SDL_SetError("Steam cloud is disabled for this application");
|
||||
goto steamfail;
|
||||
}
|
||||
if (!steam->SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch(steamremotestorage)) {
|
||||
SDL_SetError("SteamRemoteStorage()->BeginFileWriteBatch() failed");
|
||||
|
||||
result = SDL_OpenStorage(&STEAM_user_iface, steam);
|
||||
if (!result) {
|
||||
goto steamfail;
|
||||
}
|
||||
|
||||
result = SDL_OpenStorage(&STEAM_user_iface, steam);
|
||||
if (result == NULL) {
|
||||
goto steamfail;
|
||||
if (SDL_AtomicIncRef(&SDL_steam_storage_refcount) == 0) {
|
||||
if (!steam->SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch(steamremotestorage)) {
|
||||
// We probably already have a batch in progress (maybe we crashed earlier?)
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
|
||||
@@ -6,9 +6,15 @@ STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_IsCloudEnabledForApp, (void*))
|
||||
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch, (void*))
|
||||
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_EndFileWriteBatch, (void*))
|
||||
|
||||
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_FileExists, (void*, const char*))
|
||||
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_GetFileSize, (void*, const char*))
|
||||
STEAM_PROC(Sint64, SteamAPI_ISteamRemoteStorage_GetFileTimestamp, (void*, const char *))
|
||||
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileRead, (void*, const char*, void*, Sint32))
|
||||
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileWrite, (void*, const char*, const void*, Sint32))
|
||||
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_FileDelete, (void*, const char*))
|
||||
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_GetQuota, (void*, Uint64*, Uint64*))
|
||||
|
||||
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_GetFileCount, (void*))
|
||||
STEAM_PROC(const char *, SteamAPI_ISteamRemoteStorage_GetFileNameAndSize, (void*, int, Sint32*))
|
||||
|
||||
#undef STEAM_PROC
|
||||
|
||||
Reference in New Issue
Block a user