Skip to content

Commit

Permalink
Save preferences periodically if they are modified (fix aseprite#4154)
Browse files Browse the repository at this point in the history
  • Loading branch information
dacap committed Nov 22, 2023
1 parent 8226e52 commit f4d9e33
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
12 changes: 12 additions & 0 deletions src/app/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,15 @@ namespace {
CloseMainWindow(std::unique_ptr<MainWindow>& win) : m_win(win) { }
~CloseMainWindow() { m_win.reset(nullptr); }
};
// Each 10 seconds we save the modified preferences
struct SavePreferencesPeriodically {
ui::Timer m_timer;
SavePreferencesPeriodically() : m_timer(10000) {
m_timer.Tick.connect([]{ Preferences::instance().save(); });
}
~SavePreferencesPeriodically() { }
void start() { m_timer.start(); }
};
#endif

struct CloseAllDocs {
Expand Down Expand Up @@ -466,6 +475,7 @@ void App::run()
{
#ifdef ENABLE_UI
CloseMainWindow closeMainWindow(m_mainWindow);
SavePreferencesPeriodically savePrefTimer;
#endif
CloseAllDocs closeAllDocsAtExit(context());

Expand Down Expand Up @@ -543,6 +553,8 @@ void App::run()

// Run the GUI main message loop
try {
savePrefTimer.start();

manager->run();
set_app_state(AppState::kClosing);
}
Expand Down
15 changes: 15 additions & 0 deletions src/cfg/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,26 +65,32 @@ class CfgFile::CfgFileImpl {
}

void setValue(const char* section, const char* name, const char* value) {
m_dirty = true;
m_ini.SetValue(section, name, value);
}

void setBoolValue(const char* section, const char* name, bool value) {
m_dirty = true;
m_ini.SetBoolValue(section, name, value);
}

void setIntValue(const char* section, const char* name, int value) {
m_dirty = true;
m_ini.SetLongValue(section, name, value);
}

void setDoubleValue(const char* section, const char* name, double value) {
m_dirty = true;
m_ini.SetDoubleValue(section, name, value);
}

void deleteValue(const char* section, const char* name) {
m_dirty = true;
m_ini.Delete(section, name, true);
}

void deleteSection(const char* section) {
m_dirty = true;
m_ini.Delete(section, nullptr, true);
}

Expand All @@ -101,23 +107,32 @@ class CfgFile::CfgFileImpl {
return false;
}
}

m_dirty = false;
return true;
}

void save() {
if (!m_dirty)
return;

base::FileHandle file(base::open_file(m_filename, "wb"));
if (file) {
SI_Error err = m_ini.SaveFile(file.get());
if (err != SI_OK) {
LOG(ERROR, "CFG: Error %d saving configuration into %s\n",
(int)err, m_filename.c_str());
}
else {
m_dirty = false;
}
}
}

private:
std::string m_filename;
CSimpleIniA m_ini;
bool m_dirty = false;
};

CfgFile::CfgFile()
Expand Down
32 changes: 31 additions & 1 deletion src/gen/pref_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ static void print_pref_class_def(TiXmlElement* elem, const std::string& classNam
std::cout
<< indent << " void load();\n"
<< indent << " void save();\n"
<< indent << " bool isDirty() const;\n"
<< indent << " Section* section(const char* id) override;\n"
<< indent << " OptionBase* option(const char* id) override;\n";

Expand Down Expand Up @@ -200,7 +201,9 @@ static void print_pref_class_impl(TiXmlElement* elem, const std::string& prefix,

std::cout
<< "void " << prefix << className << "::save()\n"
<< "{\n";
<< "{\n"
<< " if (!isDirty())\n"
<< " return;\n";

child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
while (child) {
Expand All @@ -222,6 +225,33 @@ static void print_pref_class_impl(TiXmlElement* elem, const std::string& prefix,
<< "}\n"
<< "\n";

// Section::isDirty()

std::cout
<< "bool " << prefix << className << "::isDirty() const\n"
<< "{\n";

child = (elem->FirstChild() ? elem->FirstChild()->ToElement(): NULL);
while (child) {
if (child->Value()) {
std::string name = child->Value();
if (name == "option") {
std::string memberName = convert_xmlid_to_cppid(child->Attribute("id"), false);
std::cout << " if (" << memberName << ".isDirty()) return true;\n";
}
else if (name == "section") {
std::string memberName = convert_xmlid_to_cppid(child->Attribute("id"), false);
std::cout << " if (" << memberName << ".isDirty()) return true;\n";
}
}
child = child->NextSiblingElement();
}

std::cout
<< " return false;\n"
<< "}\n"
<< "\n";

// Section::section(id)

std::cout
Expand Down

0 comments on commit f4d9e33

Please sign in to comment.