Only save map_groups.json when relevant changes are made

This commit is contained in:
GriffinR 2026-06-13 23:20:59 -04:00
parent eaf140da84
commit 31d969c0d6
5 changed files with 35 additions and 16 deletions

View File

@ -15,6 +15,7 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp
- The dimensions of the current metatile selection are now displayed above the metatile selector.
- The 'Change Dimensions' button was replaced with a Resize tool button. Resizing is also now available under the `Edit` menu, and can be assigned a shortcut.
- Some UI changes to prioritize horizontal space for the map.
- `map_groups.json` is only saved when relevant changes are made, which should improve the average project compile time after saving with Porymap.
### Fixed
- Fix actions triggered with the use of `utility.registerAction` calling all functions across plug-ins with the registered name, rather than just the function in the script that registered it.

View File

@ -31,8 +31,6 @@ public:
public:
QString root;
QStringList groupNames;
QMap<QString, QStringList> groupNameToMapNames;
QStringList healLocationSaveOrder;
QMap<QString, QList<HealLocationEvent*>> healLocations;
QMap<QString, QString> mapConstantsToMapNames;
@ -76,6 +74,11 @@ public:
bool isLoadedMap(const QString &mapName) const { return this->loadedMapNames.contains(mapName); }
bool isUnsavedMap(const QString &mapName) const;
const QStringList& mapGroups() const { return this->groupNames; }
QStringList mapNamesInMapGroup(const QString& mapGroupName) const { return this->groupNameToMapNames.value(mapGroupName); }
void setMapGroups(const QStringList& orderedGroupNames, const QMap<QString, QStringList>& groupNameToMapNames);
bool isMapGroup(const QString &mapGroupName) const { return this->groupNames.contains(mapGroupName); }
// Note: This does not guarantee the map is loaded.
Map* getMap(const QString &mapName) { return this->maps.value(mapName); }
Map* loadMap(const QString &mapName);
@ -163,7 +166,6 @@ public:
void setMapsecDisplayName(const QString &idName, const QString &displayName);
bool hasUnsavedChanges();
bool hasUnsavedDataChanges = false;
bool loadMapEvent(Map *map, QJsonObject json, Event::Type defaultType = Event::Type::None);
bool loadMapData(Map*);
@ -316,8 +318,13 @@ private:
QSet<QString> failedFileWatchPaths;
const QRegularExpression re_gbapalExtension;
const QRegularExpression re_bppExtension;
// TODO: Unless it makes a worthwhile performance difference, these should really be
// combined into a single OrderedMap<QString, QStringList>.
QStringList groupNames;
QMap<QString, QStringList> groupNameToMapNames;
bool hasUnsavedDataChanges = false;
bool hasUnsavedMapGroupChanges = false;
struct EventGraphics
{

View File

@ -558,6 +558,8 @@ Map *Project::createNewMap(const Project::NewMapSettings &settings, const Map* t
addNewMapsec(map->header()->location());
this->groupNameToMapNames[settings.group].append(map->name());
// We don't mark that map groups has been edited until the new map is saved
this->mapConstantsToMapNames.insert(map->constantName(), map->name());
this->alphabeticalMapNames.append(map->name());
Util::numericalModeSort(this->alphabeticalMapNames);
@ -916,6 +918,8 @@ void Project::resetFileWatcher() {
}
bool Project::saveMapGroups() {
if (!this->hasUnsavedMapGroupChanges) return true;
QString mapGroupsFilepath = QString("%1/%2").arg(root).arg(projectConfig.getFilePath(ProjectFilePath::json_map_groups));
QFile mapGroupsFile(mapGroupsFilepath);
if (!mapGroupsFile.open(QIODevice::WriteOnly)) {
@ -950,6 +954,8 @@ bool Project::saveMapGroups() {
OrderedJsonDoc jsonDoc(&mapGroupJson);
jsonDoc.dump(&mapGroupsFile);
mapGroupsFile.close();
this->hasUnsavedMapGroupChanges = false;
return true;
}
@ -1361,6 +1367,9 @@ bool Project::saveMap(Map *map, bool skipLayout) {
text += QString("\t.include \"%1/text.inc\"\n").arg(folderPath);
}
appendTextFile(root + "/" + projectConfig.getFilePath(ProjectFilePath::data_event_scripts), text);
// First time saving this map, we need to update the map groups data
this->hasUnsavedMapGroupChanges = true;
}
// Create map.json for map data.
@ -2032,11 +2041,17 @@ void Project::addNewMapGroup(const QString &groupName) {
this->groupNames.append(groupName);
this->groupNameToMapNames.insert(groupName, QStringList());
this->hasUnsavedDataChanges = true;
this->hasUnsavedMapGroupChanges = true;
emit mapGroupAdded(groupName);
}
void Project::setMapGroups(const QStringList& orderedGroupNames, const QMap<QString, QStringList>& groupNameToMapNames) {
this->groupNames = orderedGroupNames;
this->groupNameToMapNames = groupNameToMapNames;
this->hasUnsavedMapGroupChanges = true;
}
QString Project::mapNameToMapGroup(const QString &mapName) const {
for (auto it = this->groupNameToMapNames.constBegin(); it != this->groupNameToMapNames.constEnd(); it++) {
if (it.value().contains(mapName)) {
@ -3547,7 +3562,7 @@ void Project::applyParsedLimits() {
}
bool Project::hasUnsavedChanges() {
if (this->hasUnsavedDataChanges)
if (this->hasUnsavedDataChanges || this->hasUnsavedMapGroupChanges)
return true;
// Check layouts for unsaved changes

View File

@ -213,9 +213,9 @@ MapGroupModel::MapGroupModel(Project *project, QObject *parent) : MapListModel(p
this->folderTypeName = "map_group";
this->editable = true;
for (const auto &groupName : this->project->groupNames) {
for (const auto &groupName : this->project->mapGroups()) {
insertMapFolderItem(groupName);
for (const auto &mapName : this->project->groupNameToMapNames.value(groupName)) {
for (const auto &mapName : this->project->mapNamesInMapGroup(groupName)) {
insertMapItem(mapName, groupName);
}
}
@ -376,7 +376,6 @@ bool MapGroupModel::dropMimeData(const QMimeData *data, Qt::DropAction action, i
void MapGroupModel::updateProject() {
if (!this->project) return;
// Temporary objects in case of failure, so we won't modify the project unless it succeeds.
QStringList groupNames;
QMap<QString, QStringList> groupNameToMapNames;
@ -394,10 +393,7 @@ void MapGroupModel::updateProject() {
groupNameToMapNames[groupName].append(mapName);
}
}
this->project->groupNames = groupNames;
this->project->groupNameToMapNames = groupNameToMapNames;
this->project->hasUnsavedDataChanges = true;
this->project->setMapGroups(groupNames, groupNameToMapNames);
}
void MapGroupModel::removeItem(QStandardItem *item) {

View File

@ -41,7 +41,7 @@ NewMapDialog::NewMapDialog(Project *project, const Map *mapToCopy, QWidget *pare
settings->layout.id = project->toUniqueIdentifier(Layout::layoutConstantFromName(settings->name));
ui->newLayoutForm->initUi(project);
ui->comboBox_Group->addItems(project->groupNames);
ui->comboBox_Group->addItems(project->mapGroups());
ui->comboBox_LayoutID->addItems(project->layoutIds());
auto validator = new IdentifierValidator(this);
@ -176,7 +176,7 @@ bool NewMapDialog::validateGroup(bool allowEmpty) {
QString errorText;
if (groupName.isEmpty()) {
if (!allowEmpty) errorText = QString("%1 cannot be empty.").arg(ui->label_Group->text());
} else if (!this->project->groupNames.contains(groupName) && !this->project->isIdentifierUnique(groupName)) {
} else if (!this->project->isMapGroup(groupName) && !this->project->isIdentifierUnique(groupName)) {
errorText = QString("%1 must either be the name of an existing map group, or a unique identifier for a new map group.").arg(ui->label_Group->text());
}