Added savestatus
This commit is contained in:
1 parent
560c51cf27
commit
08b4bbfe91
13 files changed
+502
-16
No files matched your search
@@ -1,18 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "save/savedevice.h"
|
||||
#include "save/savedevicelinux.h"
|
||||
#include "save/saveslot.h"
|
||||
#include "save/savesettings.h"
|
||||
#include "save/savejson.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/mkdirp.h"
|
||||
#include "util/string.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
errorret_t saveDeviceLinuxInit(savedevice_t *device) {
|
||||
assertNotNull(device, "device cannot be null");
|
||||
|
||||
|
||||
device->state = SAVE_DEVICE_STATE_UNKNOWN;
|
||||
|
||||
errorOk();
|
||||
@@ -31,9 +36,21 @@ void saveDeviceLinuxCheckAvailability(savedevice_t *device) {
|
||||
device->state == SAVE_DEVICE_STATE_CHECKING_AVAILABILITY,
|
||||
"Device state incorrect?"
|
||||
);
|
||||
|
||||
|
||||
// Resolve the save directory.
|
||||
char_t directory[SAVE_DEVICE_LINUX_PATH_MAX];
|
||||
errorret_t directoryResult = saveDeviceLinuxGetDirectory(
|
||||
directory, sizeof(directory)
|
||||
);
|
||||
if(errorIsNotOk(directoryResult)) {
|
||||
errorCatch(errorPrint(directoryResult));
|
||||
device->state = SAVE_DEVICE_STATE_UNAVAILABLE;
|
||||
device->reasonKey = "save.linux.no_home";
|
||||
return saveDeviceFireCallback(device);
|
||||
}
|
||||
|
||||
// Mkdirp the save directory.
|
||||
int mkdirpResult = mkdirp(SAVE_DEVICE_LINUX_DIRECTORY, 0700);
|
||||
int mkdirpResult = mkdirp(directory, 0700);
|
||||
if(mkdirpResult != 0) {
|
||||
device->state = SAVE_DEVICE_STATE_UNAVAILABLE;
|
||||
device->reasonKey = "save.linux.mkdirp_failed";
|
||||
@@ -46,6 +63,181 @@ void saveDeviceLinuxCheckAvailability(savedevice_t *device) {
|
||||
saveDeviceFireCallback(device);
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxGetDirectory(char_t *dest, const size_t destSize) {
|
||||
assertNotNull(dest, "dest cannot be null");
|
||||
|
||||
const char_t *home = getenv("HOME");
|
||||
if(home == NULL) errorThrow("HOME environment variable is not set");
|
||||
|
||||
stringFormat(dest, destSize, "%s/%s", home, SAVE_DEVICE_LINUX_DIRECTORY_NAME);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxGetSettingsPath(
|
||||
char_t *dest,
|
||||
const size_t destSize
|
||||
) {
|
||||
assertNotNull(dest, "dest cannot be null");
|
||||
|
||||
char_t directory[SAVE_DEVICE_LINUX_PATH_MAX];
|
||||
errorChain(saveDeviceLinuxGetDirectory(directory, sizeof(directory)));
|
||||
|
||||
stringFormat(
|
||||
dest, destSize, "%s/%s", directory, SAVE_DEVICE_LINUX_SETTINGS_FILENAME
|
||||
);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxGetSlotPath(
|
||||
char_t *dest,
|
||||
const size_t destSize,
|
||||
const uint8_t slotIndex
|
||||
) {
|
||||
assertNotNull(dest, "dest cannot be null");
|
||||
|
||||
char_t directory[SAVE_DEVICE_LINUX_PATH_MAX];
|
||||
errorChain(saveDeviceLinuxGetDirectory(directory, sizeof(directory)));
|
||||
|
||||
char_t filename[SAVE_SLOT_NAME_LENGTH + 16];
|
||||
stringFormat(
|
||||
filename, sizeof(filename) - 1,
|
||||
SAVE_DEVICE_LINUX_SLOT_FILENAME_FORMAT, (uint32_t)slotIndex
|
||||
);
|
||||
|
||||
stringFormat(dest, destSize, "%s/%s", directory, filename);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxSlotWrite(
|
||||
savedevice_t *device,
|
||||
saveslot_t *slot,
|
||||
uint8_t slotIndex
|
||||
) {
|
||||
assertNotNull(device, "device cannot be null");
|
||||
assertNotNull(slot, "slot cannot be null");
|
||||
|
||||
char_t path[SAVE_DEVICE_LINUX_PATH_MAX];
|
||||
errorChain(saveDeviceLinuxGetSlotPath(path, sizeof(path), slotIndex));
|
||||
|
||||
writeInit();
|
||||
|
||||
errorret_t writeResult = saveSlotWriteJSON(slot, doc, object);
|
||||
if(errorIsNotOk(writeResult)) {
|
||||
yyjson_mut_doc_free(doc);
|
||||
errorChain(writeResult);
|
||||
}
|
||||
|
||||
yyjson_write_err writeErr;
|
||||
bool_t written = yyjson_mut_write_file(path, doc, 0, NULL, &writeErr);
|
||||
yyjson_mut_doc_free(doc);
|
||||
|
||||
if(!written) {
|
||||
errorThrow(
|
||||
"Failed to write save slot file: %s (%s)", path, writeErr.msg
|
||||
);
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxSlotRead(
|
||||
savedevice_t *device,
|
||||
saveslot_t *slot,
|
||||
uint8_t slotIndex
|
||||
) {
|
||||
assertNotNull(device, "device cannot be null");
|
||||
assertNotNull(slot, "slot cannot be null");
|
||||
|
||||
char_t path[SAVE_DEVICE_LINUX_PATH_MAX];
|
||||
errorChain(saveDeviceLinuxGetSlotPath(path, sizeof(path), slotIndex));
|
||||
|
||||
yyjson_read_err readErr;
|
||||
yyjson_doc *jsonDoc = yyjson_read_file(path, 0, NULL, &readErr);
|
||||
if(jsonDoc == NULL) {
|
||||
// No save file at this slot yet, leave the slot as-is.
|
||||
if(readErr.code == YYJSON_READ_ERROR_FILE_OPEN) errorOk();
|
||||
errorThrow(
|
||||
"Failed to parse save slot file: %s (%s)", path, readErr.msg
|
||||
);
|
||||
}
|
||||
|
||||
yyjson_val *object = yyjson_doc_get_root(jsonDoc);
|
||||
if(object == NULL) {
|
||||
yyjson_doc_free(jsonDoc);
|
||||
errorThrow("Save slot file missing root object: %s", path);
|
||||
}
|
||||
|
||||
errorret_t readResult = saveSlotReadJSON(slot, object);
|
||||
yyjson_doc_free(jsonDoc);
|
||||
errorChain(readResult);
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxSettingsWrite(
|
||||
savedevice_t *device,
|
||||
savesettings_t *settings
|
||||
) {
|
||||
assertNotNull(device, "device cannot be null");
|
||||
assertNotNull(settings, "settings cannot be null");
|
||||
|
||||
char_t path[SAVE_DEVICE_LINUX_PATH_MAX];
|
||||
errorChain(saveDeviceLinuxGetSettingsPath(path, sizeof(path)));
|
||||
|
||||
writeInit();
|
||||
|
||||
errorret_t writeResult = saveSettingsWriteJSON(settings, doc, object);
|
||||
if(errorIsNotOk(writeResult)) {
|
||||
yyjson_mut_doc_free(doc);
|
||||
errorChain(writeResult);
|
||||
}
|
||||
|
||||
yyjson_write_err writeErr;
|
||||
bool_t written = yyjson_mut_write_file(path, doc, 0, NULL, &writeErr);
|
||||
yyjson_mut_doc_free(doc);
|
||||
|
||||
if(!written) {
|
||||
errorThrow(
|
||||
"Failed to write save settings file: %s (%s)", path, writeErr.msg
|
||||
);
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxSettingsRead(
|
||||
savedevice_t *device,
|
||||
savesettings_t *settings
|
||||
) {
|
||||
assertNotNull(device, "device cannot be null");
|
||||
assertNotNull(settings, "settings cannot be null");
|
||||
|
||||
char_t path[SAVE_DEVICE_LINUX_PATH_MAX];
|
||||
errorChain(saveDeviceLinuxGetSettingsPath(path, sizeof(path)));
|
||||
|
||||
yyjson_read_err readErr;
|
||||
yyjson_doc *jsonDoc = yyjson_read_file(path, 0, NULL, &readErr);
|
||||
if(jsonDoc == NULL) {
|
||||
// No settings file yet, leave settings as-is.
|
||||
if(readErr.code == YYJSON_READ_ERROR_FILE_OPEN) errorOk();
|
||||
errorThrow(
|
||||
"Failed to parse save settings file: %s (%s)", path, readErr.msg
|
||||
);
|
||||
}
|
||||
|
||||
yyjson_val *object = yyjson_doc_get_root(jsonDoc);
|
||||
if(object == NULL) {
|
||||
yyjson_doc_free(jsonDoc);
|
||||
errorThrow("Save settings file missing root object: %s", path);
|
||||
}
|
||||
|
||||
errorret_t readResult = saveSettingsReadJSON(settings, object);
|
||||
yyjson_doc_free(jsonDoc);
|
||||
errorChain(readResult);
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t saveDeviceLinuxDispose(savedevice_t *device) {
|
||||
errorOk();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user