Skip to content

Commit 67dcb22

Browse files
fix: always save on window close regardless of vector modification state
SaveToFile() was guarded on builds_changed, which only tracks structural vector modifications (add/delete/reorder). Field-level edits (name, group, build code, behavior, etc.) never set builds_changed, so they silently failed to persist when the window was closed. Since SaveToFile() is only called at meaningful checkpoints (window close, settings save — never per-frame), removing the guard is safe and correct. Co-authored-by: Jon <3vcloud@users.noreply.github.com>
1 parent bb04bae commit 67dcb22

2 files changed

Lines changed: 54 additions & 60 deletions

File tree

GWToolboxdll/Windows/BuildsWindow.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,6 @@ namespace {
609609

610610
void SaveToFile()
611611
{
612-
if (!(builds_changed || GWToolbox::SettingsFolderChanged()))
613-
return;
614612
if (inifile == nullptr) {
615613
inifile = new ToolboxIni();
616614
}

GWToolboxdll/Windows/HeroBuildsWindow.cpp

Lines changed: 54 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -705,69 +705,65 @@ void HeroBuildsWindow::LoadFromFile()
705705
void HeroBuildsWindow::SaveToFile() const
706706
{
707707
constexpr size_t buffer_size = 16;
708-
if (builds_changed || GWToolbox::SettingsFolderChanged()) {
709-
// clear builds from ini
710-
inifile->Reset();
711-
712-
// then save
713-
for (size_t i = 0; i < teambuilds.size(); i++) {
714-
const TeamBuild& tbuild = teambuilds[i];
715-
char section[buffer_size];
716-
snprintf(section, buffer_size, "builds%03d", i);
717-
inifile->SetValue(section, "buildname", tbuild.name.c_str());
718-
inifile->SetValue(section, "uiid", tbuild.ui_id.c_str());
719-
inifile->SetLongValue(section, "mode", tbuild.mode);
720-
if (!tbuild.group.empty())
721-
inifile->SetValue(section, "group", tbuild.group.c_str());
722-
for (size_t j = 0; j < tbuild.builds.size(); ++j) {
723-
const Build& build = tbuild.builds[j];
724-
725-
char namekey[buffer_size];
726-
char templatekey[buffer_size];
727-
char heroidkey[buffer_size];
728-
char showpanelkey[buffer_size];
729-
char behaviorkey[buffer_size];
730-
char dskillskey[buffer_size];
731-
snprintf(namekey, buffer_size, "name%d", j);
732-
snprintf(templatekey, buffer_size, "template%d", j);
733-
snprintf(heroidkey, buffer_size, "heroid%d", j);
734-
snprintf(showpanelkey, buffer_size, "panel%d", j);
735-
snprintf(behaviorkey, buffer_size, "behavior%d", j);
736-
snprintf(dskillskey, buffer_size, "dskills%d", j);
737-
inifile->SetValue(section, namekey, build.name.c_str());
738-
inifile->SetValue(section, templatekey, build.code.c_str());
739-
inifile->SetLongValue(section, heroidkey, static_cast<long>(build.hero_id));
740-
inifile->SetLongValue(section, showpanelkey, build.show_panel ? 1 : 0);
741-
inifile->SetLongValue(section, behaviorkey, build.behavior);
742-
inifile->SetLongValue(section, dskillskey, build.disabled_skills);
743-
}
744-
}
708+
inifile->Reset();
745709

746-
// Collect groups that are still referenced by at least one build.
747-
std::unordered_set<std::string> used_groups;
748-
for (const auto& tb : teambuilds) {
749-
if (!tb.group.empty()) used_groups.insert(tb.group);
750-
}
710+
for (size_t i = 0; i < teambuilds.size(); i++) {
711+
const TeamBuild& tbuild = teambuilds[i];
712+
char section[buffer_size];
713+
snprintf(section, buffer_size, "builds%03d", i);
714+
inifile->SetValue(section, "buildname", tbuild.name.c_str());
715+
inifile->SetValue(section, "uiid", tbuild.ui_id.c_str());
716+
inifile->SetLongValue(section, "mode", tbuild.mode);
717+
if (!tbuild.group.empty())
718+
inifile->SetValue(section, "group", tbuild.group.c_str());
719+
for (size_t j = 0; j < tbuild.builds.size(); ++j) {
720+
const Build& build = tbuild.builds[j];
751721

752-
// Build a sorted list of used groups; write with normalized 0-based sort_order.
753-
std::vector<std::pair<std::string, size_t>> sorted_groups;
754-
for (const auto& [name, grp] : hero_build_groups) {
755-
if (used_groups.contains(name)) {
756-
sorted_groups.push_back({name, grp.sort_order});
757-
}
758-
}
759-
std::ranges::sort(sorted_groups, [](const auto& a, const auto& b) {
760-
return a.second < b.second;
761-
});
762-
for (size_t gi = 0; gi < sorted_groups.size(); gi++) {
763-
char grp_section[32];
764-
snprintf(grp_section, sizeof(grp_section), "herobuildgroup%03zu", gi);
765-
inifile->SetValue(grp_section, "name", sorted_groups[gi].first.c_str());
766-
inifile->SetLongValue(grp_section, "sort_order", static_cast<long>(gi));
722+
char namekey[buffer_size];
723+
char templatekey[buffer_size];
724+
char heroidkey[buffer_size];
725+
char showpanelkey[buffer_size];
726+
char behaviorkey[buffer_size];
727+
char dskillskey[buffer_size];
728+
snprintf(namekey, buffer_size, "name%d", j);
729+
snprintf(templatekey, buffer_size, "template%d", j);
730+
snprintf(heroidkey, buffer_size, "heroid%d", j);
731+
snprintf(showpanelkey, buffer_size, "panel%d", j);
732+
snprintf(behaviorkey, buffer_size, "behavior%d", j);
733+
snprintf(dskillskey, buffer_size, "dskills%d", j);
734+
inifile->SetValue(section, namekey, build.name.c_str());
735+
inifile->SetValue(section, templatekey, build.code.c_str());
736+
inifile->SetLongValue(section, heroidkey, static_cast<long>(build.hero_id));
737+
inifile->SetLongValue(section, showpanelkey, build.show_panel ? 1 : 0);
738+
inifile->SetLongValue(section, behaviorkey, build.behavior);
739+
inifile->SetLongValue(section, dskillskey, build.disabled_skills);
767740
}
741+
}
742+
743+
// Collect groups that are still referenced by at least one build.
744+
std::unordered_set<std::string> used_groups;
745+
for (const auto& tb : teambuilds) {
746+
if (!tb.group.empty()) used_groups.insert(tb.group);
747+
}
768748

769-
ASSERT(inifile->SaveFile(Resources::GetSettingFile(INI_FILENAME).c_str()) == SI_OK);
749+
// Build a sorted list of used groups; write with normalized 0-based sort_order.
750+
std::vector<std::pair<std::string, size_t>> sorted_groups;
751+
for (const auto& [name, grp] : hero_build_groups) {
752+
if (used_groups.contains(name)) {
753+
sorted_groups.push_back({name, grp.sort_order});
754+
}
770755
}
756+
std::ranges::sort(sorted_groups, [](const auto& a, const auto& b) {
757+
return a.second < b.second;
758+
});
759+
for (size_t gi = 0; gi < sorted_groups.size(); gi++) {
760+
char grp_section[32];
761+
snprintf(grp_section, sizeof(grp_section), "herobuildgroup%03zu", gi);
762+
inifile->SetValue(grp_section, "name", sorted_groups[gi].first.c_str());
763+
inifile->SetLongValue(grp_section, "sort_order", static_cast<long>(gi));
764+
}
765+
766+
ASSERT(inifile->SaveFile(Resources::GetSettingFile(INI_FILENAME).c_str()) == SI_OK);
771767
}
772768

773769
TeamBuild* HeroBuildsWindow::GetTeambuildByName(const std::string& build_name_search)

0 commit comments

Comments
 (0)