Changed to a new application data directory structure

This commit is contained in:
Leon Styhre 2023-12-15 22:35:28 +01:00
parent 03e9035b7e
commit 6b0bfbfc09
7 changed files with 218 additions and 83 deletions

View file

@ -594,6 +594,32 @@ int main(int argc, char* argv[])
if (!checkApplicationDataDirectory()) if (!checkApplicationDataDirectory())
return 1; return 1;
{
if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
// Create the logs folder in the application data directory.
const std::filesystem::path logsDir {
Utils::FileSystem::getAppDataDirectory().append("logs")};
if (!Utils::FileSystem::isDirectorySTD(logsDir)) {
#if defined(__ANDROID__)
__android_log_print(ANDROID_LOG_VERBOSE, ANDROID_APPLICATION_ID,
"Creating logs directory \"%s\"...", logsDir.string().c_str());
#else
std::cout << "Creating logs directory \"" << logsDir.string() << "\"..."
<< std::endl;
#endif
Utils::FileSystem::createDirectory(logsDir.string());
if (!Utils::FileSystem::isDirectorySTD(logsDir)) {
#if defined(__ANDROID__)
__android_log_print(ANDROID_LOG_ERROR, ANDROID_APPLICATION_ID,
"Couldn't create directory, permission problems?");
#else
std::cerr << "Couldn't create directory, permission problems?" << std::endl;
#endif
}
}
}
}
// Start the logger. // Start the logger.
Log::init(); Log::init();
Log::open(); Log::open();
@ -630,90 +656,138 @@ int main(int argc, char* argv[])
Settings::getInstance()->setInt("ScreenHeight", 720); Settings::getInstance()->setInt("ScreenHeight", 720);
#endif #endif
// Check if the configuration file exists, and if not, create it. {
// This should only happen on first application startup. if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
if (!Utils::FileSystem::existsSTD( // Create the settings folder in the application data directory.
Utils::FileSystem::getAppDataDirectory().append("es_settings.xml"))) { const std::filesystem::path settingsDir {
LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it..."; Utils::FileSystem::getAppDataDirectory().append("settings")};
Settings::getInstance()->saveFile(); if (!Utils::FileSystem::isDirectorySTD(settingsDir)) {
} LOG(LogInfo) << "Creating settings directory \"" << settingsDir.string() << "\"...";
else if (settingsNeedSaving) { Utils::FileSystem::createDirectory(settingsDir.string());
LOG(LogInfo) << "Saving settings that were modified by command line options..."; if (!Utils::FileSystem::isDirectorySTD(settingsDir)) {
Settings::getInstance()->saveFile(); LOG(LogError) << "Couldn't create directory, permission problems?";
}
}
}
} }
// Check if the application release number has changed, which would normally mean that the {
// user has upgraded to a new version. // Check if the configuration file exists, and if not, create it.
int applicationRelease; std::filesystem::path settingsPath;
if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) != if (Settings::getInstance()->getBool("LegacyAppDataDirectory"))
PROGRAM_RELEASE_NUMBER) { settingsPath = Utils::FileSystem::getAppDataDirectory().append("es_settings.xml");
if (applicationRelease != 0) { else
LOG(LogInfo) << "Application release number changed from previous startup, from \"" settingsPath = Utils::FileSystem::getAppDataDirectory()
<< applicationRelease << "\" to \"" << PROGRAM_RELEASE_NUMBER << "\""; .append("settings")
.append("es_settings.xml");
if (!Utils::FileSystem::existsSTD(settingsPath)) {
LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it...";
Settings::getInstance()->saveFile();
} }
else { else if (settingsNeedSaving) {
LOG(LogInfo) << "Application release number setting is blank, changing it to \"" LOG(LogInfo) << "Saving settings that were modified by command line options...";
<< PROGRAM_RELEASE_NUMBER << "\""; Settings::getInstance()->saveFile();
} }
Settings::getInstance()->setInt("ApplicationRelease", PROGRAM_RELEASE_NUMBER);
Settings::getInstance()->saveFile();
} }
// Create the gamelists folder in the application data directory. {
const std::filesystem::path gamelistsDir { // Check if the application release number has changed, which would normally mean that the
Utils::FileSystem::getAppDataDirectory().append("gamelists")}; // user has upgraded to a new version.
if (!Utils::FileSystem::existsSTD(gamelistsDir)) { int applicationRelease;
LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir.string() << "\"..."; if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) !=
Utils::FileSystem::createDirectory(gamelistsDir.string()); PROGRAM_RELEASE_NUMBER) {
if (applicationRelease != 0) {
LOG(LogInfo) << "Application release number changed from previous startup, from \""
<< applicationRelease << "\" to \"" << PROGRAM_RELEASE_NUMBER << "\"";
}
else {
LOG(LogInfo) << "Application release number setting is blank, changing it to \""
<< PROGRAM_RELEASE_NUMBER << "\"";
}
Settings::getInstance()->setInt("ApplicationRelease", PROGRAM_RELEASE_NUMBER);
Settings::getInstance()->saveFile();
}
}
{
// Create the gamelists folder in the application data directory.
const std::filesystem::path gamelistsDir {
Utils::FileSystem::getAppDataDirectory().append("gamelists")};
if (!Utils::FileSystem::existsSTD(gamelistsDir)) { if (!Utils::FileSystem::existsSTD(gamelistsDir)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir.string() << "\"...";
Utils::FileSystem::createDirectory(gamelistsDir.string());
if (!Utils::FileSystem::existsSTD(gamelistsDir)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?";
}
} }
} }
{
#if defined(__ANDROID__) #if defined(__ANDROID__)
const std::filesystem::path themeDir { const std::filesystem::path themeDir {
Utils::FileSystem::getAppDataDirectory().append("themes")}; Utils::FileSystem::getAppDataDirectory().append("themes")};
if (!Utils::FileSystem::existsSTD(themeDir)) {
LOG(LogInfo) << "Creating themes directory \"" << themeDir.string() << "\"...";
Utils::FileSystem::createDirectory(themeDir.string());
if (!Utils::FileSystem::existsSTD(themeDir)) { if (!Utils::FileSystem::existsSTD(themeDir)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?"; LOG(LogInfo) << "Creating themes directory \"" << themeDir.string() << "\"...";
Utils::FileSystem::createDirectory(themeDir.string());
if (!Utils::FileSystem::existsSTD(themeDir)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?";
}
} }
}
#else #else
// Create the themes folder in the application data directory (or elsewhere if the // Create the themes folder in the application data directory (or elsewhere if the
// UserThemeDirectory setting has been defined). // UserThemeDirectory setting has been defined).
const std::filesystem::path defaultUserThemeDir { const std::filesystem::path defaultUserThemeDir {
Utils::FileSystem::getAppDataDirectory().append("themes")}; Utils::FileSystem::getAppDataDirectory().append("themes")};
std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath( std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath(
Settings::getInstance()->getString("UserThemeDirectory"))}; Settings::getInstance()->getString("UserThemeDirectory"))};
std::filesystem::path userThemeDirectory; std::filesystem::path userThemeDirectory;
if (userThemeDirSetting.empty()) if (userThemeDirSetting.empty())
userThemeDirectory = defaultUserThemeDir; userThemeDirectory = defaultUserThemeDir;
else else
userThemeDirectory = userThemeDirSetting; userThemeDirectory = userThemeDirSetting;
if (!Utils::FileSystem::existsSTD(userThemeDirectory)) {
LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory.string() << "\"...";
Utils::FileSystem::createDirectory(userThemeDirectory.string());
if (!Utils::FileSystem::existsSTD(userThemeDirectory)) { if (!Utils::FileSystem::existsSTD(userThemeDirectory)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?"; LOG(LogInfo) << "Creating themes directory \"" << userThemeDirectory.string()
<< "\"...";
Utils::FileSystem::createDirectory(userThemeDirectory.string());
if (!Utils::FileSystem::existsSTD(userThemeDirectory)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?";
}
}
#endif
}
{
// Create the scripts folder in the application data directory. This is only required
// for custom event scripts so it's also created as a convenience.
const std::filesystem::path scriptsDir {
Utils::FileSystem::getAppDataDirectory().append("scripts")};
if (!Utils::FileSystem::existsSTD(scriptsDir)) {
LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir.string() << "\"...";
Utils::FileSystem::createDirectory(scriptsDir.string());
if (!Utils::FileSystem::existsSTD(scriptsDir)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?";
}
} }
} }
#endif
// Create the scripts folder in the application data directory. This is only required {
// for custom event scripts so it's also created as a convenience. if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
const std::filesystem::path scriptsDir { // Create the controllers folder in the application data directory.
Utils::FileSystem::getAppDataDirectory().append("scripts")}; const std::filesystem::path controllersDir {
if (!Utils::FileSystem::existsSTD(scriptsDir)) { Utils::FileSystem::getAppDataDirectory().append("controllers")};
LOG(LogInfo) << "Creating scripts directory \"" << scriptsDir.string() << "\"..."; if (!Utils::FileSystem::existsSTD(controllersDir)) {
Utils::FileSystem::createDirectory(scriptsDir.string()); LOG(LogInfo) << "Creating controllers directory \"" << controllersDir.string()
if (!Utils::FileSystem::existsSTD(scriptsDir)) { << "\"...";
LOG(LogWarning) << "Couldn't create directory, permission problems?\n"; Utils::FileSystem::createDirectory(controllersDir.string());
if (!Utils::FileSystem::existsSTD(controllersDir)) {
LOG(LogWarning) << "Couldn't create directory, permission problems?";
}
}
} }
} }

View file

@ -41,9 +41,9 @@ namespace
constexpr int MAX_WAIT_ITER {MAX_WAIT_MS / POLL_TIME_MS}; constexpr int MAX_WAIT_ITER {MAX_WAIT_MS / POLL_TIME_MS};
constexpr char SCRAPER_RESOURCES_DIR[] {"scrapers"}; constexpr char SCRAPER_RESOURCES_DIR[] {"scrapers"};
constexpr char DEVELOPERS_JSON_FILE[] {"gamesdb_developers.json"}; constexpr char DEVELOPERS_JSON_FILE[] {"thegamesdb_developers.json"};
constexpr char PUBLISHERS_JSON_FILE[] {"gamesdb_publishers.json"}; constexpr char PUBLISHERS_JSON_FILE[] {"thegamesdb_publishers.json"};
constexpr char GENRES_JSON_FILE[] {"gamesdb_genres.json"}; constexpr char GENRES_JSON_FILE[] {"thegamesdb_genres.json"};
constexpr char DEVELOPERS_ENDPOINT[] {"/Developers"}; constexpr char DEVELOPERS_ENDPOINT[] {"/Developers"};
constexpr char PUBLISHERS_ENDPOINT[] {"/Publishers"}; constexpr char PUBLISHERS_ENDPOINT[] {"/Publishers"};
constexpr char GENRES_ENDPOINT[] {"/Genres"}; constexpr char GENRES_ENDPOINT[] {"/Genres"};

View file

@ -86,8 +86,17 @@ void InputManager::init()
// the bundled mapping is incorrect, or the SDL version is a bit older, it makes sense to be // the bundled mapping is incorrect, or the SDL version is a bit older, it makes sense to be
// able to customize this. If a controller GUID is present in the mappings file that is // able to customize this. If a controller GUID is present in the mappings file that is
// already present inside SDL, the custom mapping will overwrite the bundled one. // already present inside SDL, the custom mapping will overwrite the bundled one.
std::filesystem::path mappingsFile { std::filesystem::path mappingsFile;
Utils::FileSystem::getAppDataDirectory().append("es_controller_mappings.cfg")};
if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
mappingsFile =
Utils::FileSystem::getAppDataDirectory().append("es_controller_mappings.cfg");
}
else {
mappingsFile = Utils::FileSystem::getAppDataDirectory()
.append("controllers")
.append("es_controller_mappings.cfg");
}
if (!Utils::FileSystem::existsSTD(mappingsFile)) if (!Utils::FileSystem::existsSTD(mappingsFile))
mappingsFile = ResourceManager::getInstance().getResourcePath( mappingsFile = ResourceManager::getInstance().getResourcePath(
@ -255,12 +264,28 @@ void InputManager::doOnFinish()
std::string InputManager::getConfigPath() std::string InputManager::getConfigPath()
{ {
return Utils::FileSystem::getAppDataDirectory().append("es_input.xml").string(); if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
return Utils::FileSystem::getAppDataDirectory().append("es_input.xml").string();
}
else {
return Utils::FileSystem::getAppDataDirectory()
.append("settings")
.append("es_input.xml")
.string();
}
} }
std::string InputManager::getTemporaryConfigPath() std::string InputManager::getTemporaryConfigPath()
{ {
return Utils::FileSystem::getAppDataDirectory().append("es_temporaryinput.xml").string(); if (Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
return Utils::FileSystem::getAppDataDirectory().append("es_temporaryinput.xml").string();
}
else {
return Utils::FileSystem::getAppDataDirectory()
.append("settings")
.append("es_temporaryinput.xml")
.string();
}
} }
int InputManager::getNumConfiguredDevices() int InputManager::getNumConfiguredDevices()

View file

@ -8,6 +8,7 @@
// //
#include "Log.h" #include "Log.h"
#include "Settings.h"
#include "utils/StringUtil.h" #include "utils/StringUtil.h"
LogLevel Log::getReportingLevel() LogLevel Log::getReportingLevel()
@ -24,7 +25,11 @@ void Log::setReportingLevel(LogLevel level)
void Log::init() void Log::init()
{ {
sLogPath = Utils::FileSystem::getAppDataDirectory().append("es_log.txt"); if (Settings::getInstance()->getBool("LegacyAppDataDirectory"))
sLogPath = Utils::FileSystem::getAppDataDirectory().append("es_log.txt");
else
sLogPath = Utils::FileSystem::getAppDataDirectory().append("logs").append("es_log.txt");
Utils::FileSystem::removeFile(sLogPath.string() + ".bak"); Utils::FileSystem::removeFile(sLogPath.string() + ".bak");
// Rename the previous log file. // Rename the previous log file.
Utils::FileSystem::renameFile(sLogPath.string(), sLogPath.string() + ".bak", true); Utils::FileSystem::renameFile(sLogPath.string(), sLogPath.string() + ".bak", true);

View file

@ -46,6 +46,7 @@ namespace
"DebugGrid", "DebugGrid",
"DebugText", "DebugText",
"DebugImage", "DebugImage",
"LegacyAppDataDirectory",
"ScraperFilter", "ScraperFilter",
"TransitionsSystemToSystem", "TransitionsSystemToSystem",
"TransitionsSystemToGamelist", "TransitionsSystemToGamelist",
@ -77,6 +78,8 @@ Settings::Settings()
{ {
mWasChanged = false; mWasChanged = false;
setDefaults(); setDefaults();
if (Utils::FileSystem::getAppDataDirectory().filename().string() == ".emulationstation")
mBoolMap["LegacyAppDataDirectory"] = std::make_pair(true, true);
loadFile(); loadFile();
} }
@ -347,6 +350,7 @@ void Settings::setDefaults()
mBoolMap["DebugGrid"] = {false, false}; mBoolMap["DebugGrid"] = {false, false};
mBoolMap["DebugText"] = {false, false}; mBoolMap["DebugText"] = {false, false};
mBoolMap["DebugImage"] = {false, false}; mBoolMap["DebugImage"] = {false, false};
mBoolMap["LegacyAppDataDirectory"] = {false, false};
mIntMap["ScraperFilter"] = {0, 0}; mIntMap["ScraperFilter"] = {0, 0};
mIntMap["TransitionsSystemToSystem"] = {ViewTransitionAnimation::INSTANT, mIntMap["TransitionsSystemToSystem"] = {ViewTransitionAnimation::INSTANT,
ViewTransitionAnimation::INSTANT}; ViewTransitionAnimation::INSTANT};
@ -364,9 +368,14 @@ void Settings::setDefaults()
void Settings::saveFile() void Settings::saveFile()
{ {
LOG(LogDebug) << "Settings::saveFile(): Saving settings to es_settings.xml"; std::filesystem::path path;
const std::filesystem::path path { if (mBoolMap["LegacyAppDataDirectory"].second == true) {
Utils::FileSystem::getAppDataDirectory().append("es_settings.xml")}; path = Utils::FileSystem::getAppDataDirectory().append("es_settings.xml");
}
else {
path =
Utils::FileSystem::getAppDataDirectory().append("settings").append("es_settings.xml");
}
pugi::xml_document doc; pugi::xml_document doc;
@ -396,18 +405,24 @@ void Settings::saveFile()
void Settings::loadFile() void Settings::loadFile()
{ {
std::filesystem::path configFile { std::filesystem::path path;
Utils::FileSystem::getAppDataDirectory().append("es_settings.xml")}; if (mBoolMap["LegacyAppDataDirectory"].second == true) {
path = Utils::FileSystem::getAppDataDirectory().append("es_settings.xml");
}
else {
path =
Utils::FileSystem::getAppDataDirectory().append("settings").append("es_settings.xml");
}
if (!Utils::FileSystem::existsSTD(configFile)) if (!Utils::FileSystem::existsSTD(path))
return; return;
pugi::xml_document doc; pugi::xml_document doc;
#if defined(_WIN64) #if defined(_WIN64)
pugi::xml_parse_result result { pugi::xml_parse_result result {
doc.load_file(Utils::String::stringToWideString(configFile.string()).c_str())}; doc.load_file(Utils::String::stringToWideString(path.string()).c_str())};
#else #else
pugi::xml_parse_result result {doc.load_file(configFile.string().c_str())}; pugi::xml_parse_result result {doc.load_file(path.string().c_str())};
#endif #endif
if (!result) { if (!result) {
LOG(LogError) << "Couldn't parse the es_settings.xml file: " << result.description(); LOG(LogError) << "Couldn't parse the es_settings.xml file: " << result.description();

View file

@ -199,7 +199,7 @@ namespace Utils
return homePath; return homePath;
#if defined(__ANDROID__) #if defined(__ANDROID__)
homePath = AndroidVariables::sAppDataDirectory; homePath = FileSystemVariables::sAppDataDirectory;
return homePath; return homePath;
#endif #endif
@ -248,7 +248,7 @@ namespace Utils
#if defined(__ANDROID__) #if defined(__ANDROID__)
homePathSTD = homePathSTD =
std::filesystem::path {getGenericPath(AndroidVariables::sAppDataDirectory)}; std::filesystem::path {getGenericPath(FileSystemVariables::sAppDataDirectory)};
return homePathSTD; return homePathSTD;
#endif #endif
#if defined(_WIN64) #if defined(_WIN64)
@ -318,7 +318,17 @@ namespace Utils
#if defined(__ANDROID__) #if defined(__ANDROID__)
return getHomePathSTD(); return getHomePathSTD();
#else #else
return getHomePathSTD().append(".emulationstation"); if (FileSystemVariables::sAppDataDirectory.empty()) {
if (Utils::FileSystem::existsSTD(getHomePathSTD().append(".emulationstation"))) {
FileSystemVariables::sAppDataDirectory =
getHomePathSTD().append(".emulationstation");
}
else {
FileSystemVariables::sAppDataDirectory = getHomePathSTD().append("ES-DE");
}
}
return FileSystemVariables::sAppDataDirectory;
#endif #endif
} }

View file

@ -15,6 +15,12 @@
#include <list> #include <list>
#include <string> #include <string>
class FileSystemVariables
{
public:
static inline std::filesystem::path sAppDataDirectory;
};
namespace Utils namespace Utils
{ {
namespace FileSystem namespace FileSystem