Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] EE - Config files for each System #93

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions es-app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ set(ES_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/FileData.h
${CMAKE_CURRENT_SOURCE_DIR}/src/FileSorts.h
${CMAKE_CURRENT_SOURCE_DIR}/src/MetaData.h
${CMAKE_CURRENT_SOURCE_DIR}/src/PlatformId.h
${CMAKE_CURRENT_SOURCE_DIR}/src/PlatformId.h
${CMAKE_CURRENT_SOURCE_DIR}/src/PerSystemConf.h # emuelec
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.h
${CMAKE_CURRENT_SOURCE_DIR}/src/Gamelist.h
${CMAKE_CURRENT_SOURCE_DIR}/src/Genres.h
Expand Down Expand Up @@ -112,7 +113,8 @@ set(ES_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/FileSorts.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/MetaData.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/PlatformId.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/PlatformId.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/PerSystemConf.cpp # emuelec
${CMAKE_CURRENT_SOURCE_DIR}/src/SystemData.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Gamelist.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/Genres.cpp
Expand Down
266 changes: 266 additions & 0 deletions es-app/src/PerSystemConf.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
#include "PerSystemConf.h"
#include <iostream>
#include <fstream>
#include "Log.h"
#include "utils/StringUtil.h"
#include "utils/FileSystemUtil.h"
#include "Settings.h"
#include "Paths.h"
#include "Paths.h"
#include "FileData.h"

#include <set>
#include <regex>
#include <string>
#include <iostream>
#include <SDL_timer.h>

static std::set<std::string> dontRemoveValue
{
};

static std::map<std::string, std::string> defaults =
{
};

std::map<std::string, PerSystemConf*> PerSystemConf::instanceMap;

PerSystemConf *PerSystemConf::getInstance(SystemData *sysData)
{
std::string name = sysData->getName();

if (instanceMap.count(name) == 0) {
std::string path = sysData->getRootFolder()->getPath();
instanceMap[name] = new PerSystemConf(path + "/system.cfg");
}

return instanceMap[name];
}

bool PerSystemConf::saveAllSystemConf()
{
for (auto& it : instanceMap)
{
it.second->saveSystemConf();
}
return true;
}

PerSystemConf::PerSystemConf(): mWasChanged(false), mSystemConfFile(""), confMap()
{

}

PerSystemConf::PerSystemConf(std::string filepath): mWasChanged(false), mSystemConfFile(filepath), confMap()
{
if (filepath.empty()) {
return;
}

//mSystemConfFile = filepath;
mSystemConfFileTmp = filepath + ".tmp";

LOG(LogWarning) << "mSystemConfFile:" << mSystemConfFile;

if (!Utils::FileSystem::exists(mSystemConfFile)) {
Utils::FileSystem::writeAllText(mSystemConfFile, "");
return;
}

if (Utils::FileSystem::readAllText(mSystemConfFile).empty()) {
LOG(LogWarning) << "mSystemConfFile:" << mSystemConfFile << "No text skipping.";
return;
}

LOG(LogWarning) << "loadSystemConf()";
loadSystemConf();
}

PerSystemConf::~PerSystemConf()
{
}

bool PerSystemConf::loadSystemConf()
{
if (mSystemConfFile.empty())
return true;

mWasChanged = false;

std::string line;
std::ifstream systemConf(mSystemConfFile);
if (systemConf && systemConf.is_open())
{
if (systemConf.eof())
return true;

while (std::getline(systemConf, line))
{
LOG(LogWarning) << "systemConf line: " << line;
int idx = line.find("=");
if (idx == std::string::npos || line.find("#") == 0 || line.find(";") == 0)
continue;

std::string key = line.substr(0, idx);
std::string value = line.substr(idx + 1);
if (!key.empty() && !value.empty())
confMap[key] = value;

}
systemConf.close();
}
else
{
LOG(LogError) << "Unable to open " << mSystemConfFile;
return false;
}

return true;
}

bool PerSystemConf::saveSystemConf()
{
if (mSystemConfFile.empty())
return false;

if (!mWasChanged)
return false;

std::ifstream filein(mSystemConfFile); //File to read from

#ifndef WIN32
if (!filein)
{
LOG(LogError) << "Unable to open for saving : " << mSystemConfFile << "\n";
return false;
}
#endif

/* Read all lines in a vector */
std::vector<std::string> fileLines;
std::string line;

if (filein)
{
while (std::getline(filein, line))
fileLines.push_back(line);

filein.close();
}

static std::string removeID = "$^é(p$^mpv$êrpver$^vper$vper$^vper$vper$vper$^vperv^pervncvizn";

int lastTime = SDL_GetTicks();

/* Save new value if exists */
for (auto& it : confMap)
{
std::string key = it.first + "=";
char key0 = key[0];

bool lineFound = false;

for (auto& currentLine : fileLines)
{
if (currentLine.size() < 3)
continue;

char fc = currentLine[0];
if (fc != key0 && currentLine[1] != key0)
continue;

int idx = currentLine.find(key);
if (idx == std::string::npos)
continue;

if (idx == 0 || (idx == 1 && (fc == ';' || fc == '#')))
{
std::string val = it.second;
if ((!val.empty() && val != "auto") || dontRemoveValue.find(it.first) != dontRemoveValue.cend())
{
auto defaultValue = defaults.find(key);
if (defaultValue != defaults.cend() && defaultValue->second == val)
currentLine = removeID;
else
currentLine = key + val;
}
else
currentLine = removeID;

lineFound = true;
}
}

if (!lineFound)
{
std::string val = it.second;
if (!val.empty() && val != "auto")
fileLines.push_back(key + val);
}
}

lastTime = SDL_GetTicks() - lastTime;

LOG(LogDebug) << "saveSystemConf : " << lastTime;

std::ofstream fileout(mSystemConfFileTmp); //Temporary file
if (!fileout)
{
LOG(LogError) << "Unable to open for saving : " << mSystemConfFileTmp << "\n";
return false;
}
for (int i = 0; i < fileLines.size(); i++)
{
if (fileLines[i] != removeID)
fileout << fileLines[i] << "\n";
}

fileout.close();

std::ifstream src(mSystemConfFileTmp, std::ios::binary);
std::ofstream dst(mSystemConfFile, std::ios::binary);
dst << src.rdbuf();

remove(mSystemConfFileTmp.c_str());
mWasChanged = false;

return true;
}

std::string PerSystemConf::get(const std::string &name)
{
auto it = confMap.find(name);
if (it != confMap.cend())
return it->second;

auto dit = defaults.find(name);
if (dit != defaults.cend())
return dit->second;

return "";
}

bool PerSystemConf::set(const std::string &name, const std::string &value)
{
if (confMap.count(name) == 0 || confMap[name] != value)
{
confMap[name] = value;
mWasChanged = true;
return true;
}

return false;
}

bool PerSystemConf::getBool(const std::string &name, bool defaultValue)
{
if (defaultValue)
return get(name) != "0";

return get(name) == "1";
}

bool PerSystemConf::setBool(const std::string &name, bool value)
{
return set(name, value ? "1" : "0");
}
39 changes: 39 additions & 0 deletions es-app/src/PerSystemConf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef EMULATIONSTATION_PER_SYSTEMCONF_H
#define EMULATIONSTATION_PER_SYSTEMCONF_H

#include "SystemData.h"

#include <string>
#include <map>

class PerSystemConf
{
public:
static PerSystemConf* getInstance(SystemData* sysData);
static bool saveAllSystemConf();

PerSystemConf();
PerSystemConf(std::string filepath);
~PerSystemConf();

bool loadSystemConf();
bool saveSystemConf();

std::string get(const std::string &name);
bool set(const std::string &name, const std::string &value);

bool getBool(const std::string &name, bool defaultValue = false);
bool setBool(const std::string &name, bool value);

private:
std::map<std::string, std::string> confMap;
bool mWasChanged;

std::string mSystemConfFile;
std::string mSystemConfFileTmp;

static std::map<std::string, PerSystemConf*> instanceMap;
};


#endif //EMULATIONSTATION_PER_SYSTEMCONF_H
14 changes: 11 additions & 3 deletions es-app/src/guis/GuiMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@
#include "TextToSpeech.h"
#include "Paths.h"

#ifdef _ENABLEEMUELEC
#include "PerSystemConf.h"
#endif

#if WIN32
#include "Win32ApiSystem.h"
#endif
Expand Down Expand Up @@ -5202,7 +5206,7 @@ void GuiMenu::popSpecificConfigurationGui(Window* mWindow, std::string title, st
auto videoNativeResolutionMode_choice = createNativeVideoResolutionModeOptionList(mWindow, configName);
systemConfiguration->addWithLabel(_("NATIVE VIDEO"), videoNativeResolutionMode_choice);

const std::function<void()> video_changed([mWindow, configName, videoNativeResolutionMode_choice] {
const std::function<void()> video_changed([mWindow, configName, videoNativeResolutionMode_choice, systemData] {

std::string def_video;
std::string video_choice = videoNativeResolutionMode_choice->getSelected();
Expand All @@ -5219,14 +5223,18 @@ void GuiMenu::popSpecificConfigurationGui(Window* mWindow, std::string title, st
}
}

const std::function<void()> saveFunc([configName, videoNativeResolutionMode_choice] {
const std::function<void()> saveFunc([configName, videoNativeResolutionMode_choice, systemData] {
SystemConf::getInstance()->set(configName + ".nativevideo", videoNativeResolutionMode_choice->getSelected());
//PerSystemConf::getInstance(systemData)->set("nativevideo", videoNativeResolutionMode_choice->getSelected());
//PerSystemConf::saveAllSystemConf(); // example saves all configs
SystemConf::getInstance()->saveSystemConf();
});

const std::function<void()> abortFunc([configName, videoNativeResolutionMode_choice] {
const std::function<void()> abortFunc([configName, videoNativeResolutionMode_choice, systemData] {
videoNativeResolutionMode_choice->selectFirstItem();
SystemConf::getInstance()->set(configName + ".nativevideo", "");
//PerSystemConf::getInstance(systemData)->set("nativevideo", "");
//PerSystemConf::getInstance(systemData)->saveSystemConf(); // example saves one config only.
SystemConf::getInstance()->saveSystemConf();
});

Expand Down