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())
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.
Log::init();
Log::open();
@ -630,90 +656,138 @@ int main(int argc, char* argv[])
Settings::getInstance()->setInt("ScreenHeight", 720);
#endif
// Check if the configuration file exists, and if not, create it.
// This should only happen on first application startup.
if (!Utils::FileSystem::existsSTD(
Utils::FileSystem::getAppDataDirectory().append("es_settings.xml"))) {
LOG(LogInfo) << "Settings file es_settings.xml does not exist, creating it...";
Settings::getInstance()->saveFile();
}
else if (settingsNeedSaving) {
LOG(LogInfo) << "Saving settings that were modified by command line options...";
Settings::getInstance()->saveFile();
{
if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
// Create the settings folder in the application data directory.
const std::filesystem::path settingsDir {
Utils::FileSystem::getAppDataDirectory().append("settings")};
if (!Utils::FileSystem::isDirectorySTD(settingsDir)) {
LOG(LogInfo) << "Creating settings directory \"" << settingsDir.string() << "\"...";
Utils::FileSystem::createDirectory(settingsDir.string());
if (!Utils::FileSystem::isDirectorySTD(settingsDir)) {
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.
int applicationRelease;
if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) !=
PROGRAM_RELEASE_NUMBER) {
if (applicationRelease != 0) {
LOG(LogInfo) << "Application release number changed from previous startup, from \""
<< applicationRelease << "\" to \"" << PROGRAM_RELEASE_NUMBER << "\"";
{
// Check if the configuration file exists, and if not, create it.
std::filesystem::path settingsPath;
if (Settings::getInstance()->getBool("LegacyAppDataDirectory"))
settingsPath = Utils::FileSystem::getAppDataDirectory().append("es_settings.xml");
else
settingsPath = Utils::FileSystem::getAppDataDirectory()
.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 {
LOG(LogInfo) << "Application release number setting is blank, changing it to \""
<< PROGRAM_RELEASE_NUMBER << "\"";
else if (settingsNeedSaving) {
LOG(LogInfo) << "Saving settings that were modified by command line options...";
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 {
Utils::FileSystem::getAppDataDirectory().append("gamelists")};
if (!Utils::FileSystem::existsSTD(gamelistsDir)) {
LOG(LogInfo) << "Creating gamelists directory \"" << gamelistsDir.string() << "\"...";
Utils::FileSystem::createDirectory(gamelistsDir.string());
{
// Check if the application release number has changed, which would normally mean that the
// user has upgraded to a new version.
int applicationRelease;
if ((applicationRelease = Settings::getInstance()->getInt("ApplicationRelease")) !=
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)) {
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__)
const std::filesystem::path themeDir {
Utils::FileSystem::getAppDataDirectory().append("themes")};
if (!Utils::FileSystem::existsSTD(themeDir)) {
LOG(LogInfo) << "Creating themes directory \"" << themeDir.string() << "\"...";
Utils::FileSystem::createDirectory(themeDir.string());
const std::filesystem::path themeDir {
Utils::FileSystem::getAppDataDirectory().append("themes")};
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
// Create the themes folder in the application data directory (or elsewhere if the
// UserThemeDirectory setting has been defined).
const std::filesystem::path defaultUserThemeDir {
Utils::FileSystem::getAppDataDirectory().append("themes")};
std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath(
Settings::getInstance()->getString("UserThemeDirectory"))};
std::filesystem::path userThemeDirectory;
// Create the themes folder in the application data directory (or elsewhere if the
// UserThemeDirectory setting has been defined).
const std::filesystem::path defaultUserThemeDir {
Utils::FileSystem::getAppDataDirectory().append("themes")};
std::filesystem::path userThemeDirSetting {Utils::FileSystem::expandHomePath(
Settings::getInstance()->getString("UserThemeDirectory"))};
std::filesystem::path userThemeDirectory;
if (userThemeDirSetting.empty())
userThemeDirectory = defaultUserThemeDir;
else
userThemeDirectory = userThemeDirSetting;
if (userThemeDirSetting.empty())
userThemeDirectory = defaultUserThemeDir;
else
userThemeDirectory = userThemeDirSetting;
if (!Utils::FileSystem::existsSTD(userThemeDirectory)) {
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?";
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.
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?\n";
{
if (!Settings::getInstance()->getBool("LegacyAppDataDirectory")) {
// Create the controllers folder in the application data directory.
const std::filesystem::path controllersDir {
Utils::FileSystem::getAppDataDirectory().append("controllers")};
if (!Utils::FileSystem::existsSTD(controllersDir)) {
LOG(LogInfo) << "Creating controllers directory \"" << controllersDir.string()
<< "\"...";
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 char SCRAPER_RESOURCES_DIR[] {"scrapers"};
constexpr char DEVELOPERS_JSON_FILE[] {"gamesdb_developers.json"};
constexpr char PUBLISHERS_JSON_FILE[] {"gamesdb_publishers.json"};
constexpr char GENRES_JSON_FILE[] {"gamesdb_genres.json"};
constexpr char DEVELOPERS_JSON_FILE[] {"thegamesdb_developers.json"};
constexpr char PUBLISHERS_JSON_FILE[] {"thegamesdb_publishers.json"};
constexpr char GENRES_JSON_FILE[] {"thegamesdb_genres.json"};
constexpr char DEVELOPERS_ENDPOINT[] {"/Developers"};
constexpr char PUBLISHERS_ENDPOINT[] {"/Publishers"};
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
// 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.
std::filesystem::path mappingsFile {
Utils::FileSystem::getAppDataDirectory().append("es_controller_mappings.cfg")};
std::filesystem::path mappingsFile;
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))
mappingsFile = ResourceManager::getInstance().getResourcePath(
@ -255,12 +264,28 @@ void InputManager::doOnFinish()
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()
{
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()

View file

@ -8,6 +8,7 @@
//
#include "Log.h"
#include "Settings.h"
#include "utils/StringUtil.h"
LogLevel Log::getReportingLevel()
@ -24,7 +25,11 @@ void Log::setReportingLevel(LogLevel level)
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");
// Rename the previous log file.
Utils::FileSystem::renameFile(sLogPath.string(), sLogPath.string() + ".bak", true);

View file

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

View file

@ -199,7 +199,7 @@ namespace Utils
return homePath;
#if defined(__ANDROID__)
homePath = AndroidVariables::sAppDataDirectory;
homePath = FileSystemVariables::sAppDataDirectory;
return homePath;
#endif
@ -248,7 +248,7 @@ namespace Utils
#if defined(__ANDROID__)
homePathSTD =
std::filesystem::path {getGenericPath(AndroidVariables::sAppDataDirectory)};
std::filesystem::path {getGenericPath(FileSystemVariables::sAppDataDirectory)};
return homePathSTD;
#endif
#if defined(_WIN64)
@ -318,7 +318,17 @@ namespace Utils
#if defined(__ANDROID__)
return getHomePathSTD();
#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
}

View file

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