1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-24 08:32:34 +02:00

Settings: savefrequency is now configurable in launcher

* Client command-line can modify arbitrary settings now
* Only launcher auto-saves to settings.json
This commit is contained in:
Henning Koehler 2018-04-03 13:37:09 +12:00 committed by ArseniyShestakov
parent ce0b4b222d
commit 2ede3783dd
12 changed files with 119 additions and 24 deletions

View File

@ -61,6 +61,7 @@
#include <boost/asio.hpp>
#include "mainmenu/CPrologEpilogVideo.h"
#include <vstd/StringUtils.h>
#ifdef VCMI_WINDOWS
#include "SDL_syswm.h"
@ -259,7 +260,29 @@ int main(int argc, char * argv[])
preinitDLL(::console);
settings.init();
Settings session = settings.write["session"];
session["onlyai"].Bool() = vm.count("onlyAI");
auto setSettingBool = [](std::string key, std::string arg) {
Settings s = settings.write(vstd::split(key, "/"));
if(::vm.count(arg))
s->Bool() = true;
else if(s->isNull())
s->Bool() = false;
};
auto setSettingInteger = [](std::string key, std::string arg, si64 defaultValue) {
Settings s = settings.write(vstd::split(key, "/"));
if(::vm.count(arg))
s->Integer() = ::vm[arg].as<si64>();
else if(s->isNull())
s->Integer() = defaultValue;
};
auto setSettingString = [](std::string key, std::string arg, std::string defaultValue) {
Settings s = settings.write(vstd::split(key, "/"));
if(::vm.count(arg))
s->String() = ::vm[arg].as<std::string>();
else if(s->isNull())
s->String() = defaultValue;
};
setSettingBool("session/onlyai", "onlyAI");
if(vm.count("headless"))
{
session["headless"].Bool() = true;
@ -277,19 +300,20 @@ int main(int argc, char * argv[])
session["spectate-battle-speed"].Float() = vm["spectate-battle-speed"].as<int>();
}
// Server settings
session["donotstartserver"].Bool() = vm.count("donotstartserver");
setSettingBool("session/donotstartserver", "donotstartserver");
// Shared memory options
session["disable-shm"].Bool() = vm.count("disable-shm");
session["enable-shm-uuid"].Bool() = vm.count("enable-shm-uuid");
setSettingBool("session/disable-shm", "disable-shm");
setSettingBool("session/enable-shm-uuid", "enable-shm-uuid");
// Init special testing settings
session["serverport"].Integer() = vm.count("serverport") ? vm["serverport"].as<si64>() : 0;
session["saveprefix"].String() = vm.count("saveprefix") ? vm["saveprefix"].as<std::string>() : "";
session["savefrequency"].Integer() = vm.count("savefrequency") ? vm["savefrequency"].as<si64>() : 1;
setSettingInteger("session/serverport", "serverport", 0);
setSettingString("session/saveprefix", "saveprefix", "");
setSettingInteger("general/saveFrequency", "savefrequency", 1);
// Initialize logging based on settings
logConfig.configure();
logGlobal->debug("settings = %s", settings.toJsonNode().toJson());
// Some basic data validation to produce better error messages in cases of incorrect install
auto testFile = [](std::string filename, std::string message) -> bool

View File

@ -165,6 +165,7 @@ void CPlayerInterface::yourTurn()
adventureInt->selection = nullptr;
std::string prefix = settings["session"]["saveprefix"].String();
int frequency = settings["general"]["saveFrequency"].Integer();
if (firstCall)
{
if(CSH->howManyPlayerInterfaces() == 1)
@ -180,7 +181,7 @@ void CPlayerInterface::yourTurn()
}
firstCall = 0;
}
else if (cb->getDate() % static_cast<int>(settings["session"]["savefrequency"].Integer()) == 0)
else if(frequency > 0 && cb->getDate() % frequency == 0)
{
LOCPLINT->cb->save("Saves/" + prefix + "Autosave_" + boost::lexical_cast<std::string>(autosaveCount++ + 1));
autosaveCount %= 5;

View File

@ -17,7 +17,7 @@
"type" : "object",
"default": {},
"additionalProperties" : false,
"required" : [ "playerName", "showfps", "music", "sound", "encoding", "swipe", "saveRandomMaps" ],
"required" : [ "playerName", "showfps", "music", "sound", "encoding", "swipe", "saveRandomMaps", "saveFrequency" ],
"properties" : {
"playerName" : {
"type":"string",
@ -58,6 +58,10 @@
"lastCampaign" : {
"type":"string",
"default" : ""
},
"saveFrequency" : {
"type" : "number",
"default" : 1
}
}
},

View File

@ -0,0 +1,6 @@
namespace vstd
{
DLL_LINKAGE std::vector<std::string> split(std::string s, std::string separators);
}

View File

@ -36,7 +36,7 @@ void MainWindow::load()
QDir::addSearchPath("icons", pathToQString(string / "launcher" / "icons"));
QDir::addSearchPath("icons", pathToQString(VCMIDirs::get().userDataPath() / "launcher" / "icons"));
settings.init();
settings.init(true);
}
MainWindow::MainWindow(QWidget * parent) :

View File

@ -94,6 +94,7 @@ void CSettingsView::loadSettings()
size_t encodingIndex = boost::range::find(knownEncodingsList, encoding) - knownEncodingsList;
if (encodingIndex < ui->comboBoxEncoding->count())
ui->comboBoxEncoding->setCurrentIndex(encodingIndex);
ui->comboBoxAutoSave->setCurrentIndex(settings["general"]["saveFrequency"].Integer() > 0 ? 1 : 0);
}
CSettingsView::CSettingsView(QWidget *parent) :
@ -223,3 +224,9 @@ void CSettingsView::on_changeGameDataDir_clicked()
{
}
void CSettingsView::on_comboBoxAutoSave_currentIndexChanged(int index)
{
Settings node = settings.write["general"]["saveFrequency"];
node->Integer() = index;
}

View File

@ -59,6 +59,8 @@ private slots:
void on_comboBoxDisplayIndex_currentIndexChanged(int index);
void on_comboBoxAutoSave_currentIndexChanged(int index);
private:
Ui::CSettingsView *ui;
};

View File

@ -603,6 +603,30 @@
</property>
</widget>
</item>
<item row="11" column="6">
<widget class="QLabel" name="labelAutoSave">
<property name="text">
<string>Autosave</string>
</property>
</widget>
</item>
<item row="11" column="7">
<widget class="QComboBox" name="comboBoxAutoSave">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>Off</string>
</property>
</item>
<item>
<property name="text">
<string>On</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@ -42,7 +42,7 @@ SettingsStorage::NodeAccessor<Accessor>::operator Accessor() const
}
template<typename Accessor>
SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>::operator () (std::vector<std::string> _path)
SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>::operator () (std::vector<std::string> _path) const
{
std::vector<std::string> newPath = path;
newPath.insert( newPath.end(), _path.begin(), _path.end());
@ -51,11 +51,12 @@ SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>:
SettingsStorage::SettingsStorage():
write(NodeAccessor<Settings>(*this, std::vector<std::string>() )),
listen(NodeAccessor<SettingsListener>(*this, std::vector<std::string>() ))
listen(NodeAccessor<SettingsListener>(*this, std::vector<std::string>() )),
autoSaveConfig(false)
{
}
void SettingsStorage::init()
void SettingsStorage::init(bool autoSave)
{
std::string confName = "config/settings.json";
@ -67,6 +68,7 @@ void SettingsStorage::init()
JsonUtils::maximize(config, "vcmi:settings");
JsonUtils::validate(config, "vcmi:settings", "settings");
autoSaveConfig = autoSave;
}
void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath)
@ -74,14 +76,14 @@ void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath
for(SettingsListener * listener : listeners)
listener->nodeInvalidated(changedPath);
JsonNode savedConf = config;
JsonNode schema(ResourceID("config/schemas/settings.json"));
if(autoSaveConfig)
{
JsonNode savedConf = config;
JsonUtils::minimize(savedConf, "vcmi:settings");
savedConf.Struct().erase("session");
JsonUtils::minimize(savedConf, "vcmi:settings");
FileStream file(*CResourceHandler::get()->getResourceName(ResourceID("config/settings.json")), std::ofstream::out | std::ofstream::trunc);
file << savedConf.toJson();
FileStream file(*CResourceHandler::get()->getResourceName(ResourceID("config/settings.json")), std::ofstream::out | std::ofstream::trunc);
file << savedConf.toJson();
}
}
JsonNode & SettingsStorage::getNode(std::vector<std::string> path)
@ -98,11 +100,16 @@ Settings SettingsStorage::get(std::vector<std::string> path)
return Settings(*this, path);
}
const JsonNode& SettingsStorage::operator [](std::string value)
const JsonNode & SettingsStorage::operator [](std::string value) const
{
return config[value];
}
const JsonNode & SettingsStorage::toJsonNode() const
{
return config;
}
SettingsListener::SettingsListener(SettingsStorage &_parent, const std::vector<std::string> &_path):
parent(_parent),
path(_path)

View File

@ -26,12 +26,14 @@ class DLL_LINKAGE SettingsStorage
NodeAccessor(SettingsStorage & _parent, std::vector<std::string> _path);
NodeAccessor<Accessor> operator [] (std::string nextNode) const;
NodeAccessor<Accessor> operator () (std::vector<std::string> _path);
NodeAccessor<Accessor> operator () (std::vector<std::string> _path) const;
operator Accessor() const;
};
std::set<SettingsListener*> listeners;
JsonNode config;
bool autoSaveConfig;
JsonNode & getNode(std::vector<std::string> path);
// Calls all required listeners
@ -41,7 +43,7 @@ class DLL_LINKAGE SettingsStorage
public:
// Initialize config structure
SettingsStorage();
void init();
void init(bool autoSave=false);
// Get write access to config node at path
const NodeAccessor<Settings> write;
@ -50,7 +52,8 @@ public:
const NodeAccessor<SettingsListener> listen;
//Read access, see JsonNode::operator[]
const JsonNode& operator [](std::string value);
const JsonNode & operator [](std::string value) const;
const JsonNode & toJsonNode() const;
friend class SettingsListener;
friend class Settings;

View File

@ -124,6 +124,8 @@ set(lib_SRCS
spells/effects/RemoveObstacle.cpp
spells/effects/Sacrifice.cpp
vstd/StringUtils.cpp
CAndroidVMHelper.cpp
CArtHandler.cpp
CBonusTypeHandler.cpp
@ -169,6 +171,7 @@ set(lib_HEADERS
${CMAKE_HOME_DIRECTORY}/include/vstd/CLoggerBase.h
${CMAKE_HOME_DIRECTORY}/include/vstd/ContainerUtils.h
${CMAKE_HOME_DIRECTORY}/include/vstd/RNG.h
${CMAKE_HOME_DIRECTORY}/include/vstd/StringUtils.h
StdInc.h
../Global.h

14
lib/vstd/StringUtils.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "StdInc.h"
#include <vstd/StringUtils.h>
namespace vstd
{
DLL_LINKAGE std::vector<std::string> split(std::string s, std::string separators)
{
std::vector<std::string> result;
boost::split(result, s, boost::is_any_of(separators));
return result;
}
}