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,16 +55,21 @@ typedef struct STEAM_RemoteStorage
|
|||||||
#include "SDL_steamstorage_proc.h"
|
#include "SDL_steamstorage_proc.h"
|
||||||
} STEAM_RemoteStorage;
|
} STEAM_RemoteStorage;
|
||||||
|
|
||||||
|
static SDL_AtomicInt SDL_steam_storage_refcount;
|
||||||
|
|
||||||
static bool STEAM_CloseStorage(void *userdata)
|
static bool STEAM_CloseStorage(void *userdata)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
|
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
|
||||||
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
|
void *steamremotestorage = steam->SteamAPI_SteamRemoteStorage_v016();
|
||||||
|
bool end_batch = SDL_AtomicDecRef(&SDL_steam_storage_refcount);
|
||||||
if (steamremotestorage == NULL) {
|
if (steamremotestorage == NULL) {
|
||||||
result = SDL_SetError("SteamRemoteStorage unavailable");
|
result = SDL_SetError("SteamRemoteStorage unavailable");
|
||||||
} else if (!steam->SteamAPI_ISteamRemoteStorage_EndFileWriteBatch(steamremotestorage)) {
|
} else if (end_batch) {
|
||||||
|
if (!steam->SteamAPI_ISteamRemoteStorage_EndFileWriteBatch(steamremotestorage)) {
|
||||||
result = SDL_SetError("SteamRemoteStorage()->EndFileWriteBatch() failed");
|
result = SDL_SetError("SteamRemoteStorage()->EndFileWriteBatch() failed");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
SDL_UnloadObject(steam->libsteam_api);
|
SDL_UnloadObject(steam->libsteam_api);
|
||||||
SDL_free(steam);
|
SDL_free(steam);
|
||||||
return result;
|
return result;
|
||||||
@@ -75,6 +80,67 @@ static bool STEAM_StorageReady(void *userdata)
|
|||||||
return true;
|
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)
|
static bool STEAM_GetStoragePathInfo(void *userdata, const char *path, SDL_PathInfo *info)
|
||||||
{
|
{
|
||||||
STEAM_RemoteStorage *steam = (STEAM_RemoteStorage *)userdata;
|
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");
|
return SDL_SetError("SteamRemoteStorage unavailable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!steam->SteamAPI_ISteamRemoteStorage_FileExists(steamremotestorage, path)) {
|
||||||
|
return SDL_SetError("Can't stat");
|
||||||
|
}
|
||||||
|
|
||||||
if (info) {
|
if (info) {
|
||||||
SDL_zerop(info);
|
SDL_zerop(info);
|
||||||
info->type = SDL_PATHTYPE_FILE;
|
info->type = SDL_PATHTYPE_FILE;
|
||||||
info->size = steam->SteamAPI_ISteamRemoteStorage_GetFileSize(steamremotestorage, path);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -129,6 +201,19 @@ static bool STEAM_WriteStorageFile(void *userdata, const char *path, const void
|
|||||||
return result;
|
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)
|
static Uint64 STEAM_GetStorageSpaceRemaining(void *userdata)
|
||||||
{
|
{
|
||||||
Uint64 total, remaining;
|
Uint64 total, remaining;
|
||||||
@@ -149,12 +234,12 @@ static const SDL_StorageInterface STEAM_user_iface = {
|
|||||||
sizeof(SDL_StorageInterface),
|
sizeof(SDL_StorageInterface),
|
||||||
STEAM_CloseStorage,
|
STEAM_CloseStorage,
|
||||||
STEAM_StorageReady,
|
STEAM_StorageReady,
|
||||||
NULL, // enumerate
|
STEAM_EnumerateStorageDirectory,
|
||||||
STEAM_GetStoragePathInfo,
|
STEAM_GetStoragePathInfo,
|
||||||
STEAM_ReadStorageFile,
|
STEAM_ReadStorageFile,
|
||||||
STEAM_WriteStorageFile,
|
STEAM_WriteStorageFile,
|
||||||
NULL, // mkdir
|
NULL, // mkdir
|
||||||
NULL, // remove
|
STEAM_RemoveStoragePath,
|
||||||
NULL, // rename
|
NULL, // rename
|
||||||
NULL, // copy
|
NULL, // copy
|
||||||
STEAM_GetStorageSpaceRemaining
|
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");
|
SDL_SetError("Steam cloud is disabled for this application");
|
||||||
goto steamfail;
|
goto steamfail;
|
||||||
}
|
}
|
||||||
if (!steam->SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch(steamremotestorage)) {
|
|
||||||
SDL_SetError("SteamRemoteStorage()->BeginFileWriteBatch() failed");
|
result = SDL_OpenStorage(&STEAM_user_iface, steam);
|
||||||
|
if (!result) {
|
||||||
goto steamfail;
|
goto steamfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = SDL_OpenStorage(&STEAM_user_iface, steam);
|
if (SDL_AtomicIncRef(&SDL_steam_storage_refcount) == 0) {
|
||||||
if (result == NULL) {
|
if (!steam->SteamAPI_ISteamRemoteStorage_BeginFileWriteBatch(steamremotestorage)) {
|
||||||
goto steamfail;
|
// We probably already have a batch in progress (maybe we crashed earlier?)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
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_BeginFileWriteBatch, (void*))
|
||||||
STEAM_PROC(bool, SteamAPI_ISteamRemoteStorage_EndFileWriteBatch, (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(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_FileRead, (void*, const char*, void*, Sint32))
|
||||||
STEAM_PROC(Sint32, SteamAPI_ISteamRemoteStorage_FileWrite, (void*, const char*, const 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(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
|
#undef STEAM_PROC
|
||||||
|
|||||||
Reference in New Issue
Block a user