From f8f6fe827d17ef828e0cfee9608a1d9589b56727 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 1 May 2025 15:41:37 -0400 Subject: [PATCH] Fix missing filewatcher paths --- include/core/parseutil.h | 5 +- include/core/tileset.h | 6 +-- include/project.h | 5 +- src/core/tileset.cpp | 24 ++++----- src/project.cpp | 113 +++++++++++++++++++++++++-------------- 5 files changed, 92 insertions(+), 61 deletions(-) diff --git a/include/core/parseutil.h b/include/core/parseutil.h index 09cc1ecb..2edb9f78 100644 --- a/include/core/parseutil.h +++ b/include/core/parseutil.h @@ -43,9 +43,13 @@ class ParseUtil { public: ParseUtil(); + void setRoot(const QString &dir) { this->root = dir; } void setUpdatesSplashScreen(bool updates) { this->updatesSplashScreen = updates; } + static QString readTextFile(const QString &path, QString *error = nullptr); + QString loadTextFile(const QString &path, QString *error = nullptr); + bool cacheFile(const QString &path, QString *error = nullptr); void clearFileCache() { this->fileCache.clear(); } static int textFileLineCount(const QString &path); @@ -127,7 +131,6 @@ private: QHash evaluateCDefines(const QString &filename, const QSet &filterList, bool useRegex, QString *error); bool defineNameMatchesFilter(const QString &name, const QSet &filterList) const; bool defineNameMatchesFilter(const QString &name, const QSet &filterList) const; - QString loadTextFile(const QString &path, QString *error = nullptr); QString pathWithRoot(const QString &path); static const QRegularExpression re_incScriptLabel; diff --git a/include/core/tileset.h b/include/core/tileset.h index a05afdc3..abb31ab1 100644 --- a/include/core/tileset.h +++ b/include/core/tileset.h @@ -67,9 +67,9 @@ public: bool saveTilesImage(); bool savePalettes(); - bool appendToHeaders(QString root, QString friendlyName, bool usingAsm); - bool appendToGraphics(QString root, QString friendlyName, bool usingAsm); - bool appendToMetatiles(QString root, QString friendlyName, bool usingAsm); + bool appendToHeaders(const QString &filepath, const QString &friendlyName, bool usingAsm); + bool appendToGraphics(const QString &filepath, const QString &friendlyName, bool usingAsm); + bool appendToMetatiles(const QString &filepath, const QString &friendlyName, bool usingAsm); void setTilesImage(const QImage &image); diff --git a/include/project.h b/include/project.h index 2d2b5fd1..3c11009f 100644 --- a/include/project.h +++ b/include/project.h @@ -308,7 +308,10 @@ private: void setNewLayoutBlockdata(Layout *layout); void setNewLayoutBorder(Layout *layout); - void ignoreWatchedFileTemporarily(QString filepath); + void watchFile(const QString &filename); + void watchFiles(const QStringList &filenames); + void ignoreWatchedFileTemporarily(const QString &filepath); + void ignoreWatchedFilesTemporarily(const QStringList &filepaths); void recordFileChange(const QString &filepath); void resetFileCache(); diff --git a/src/core/tileset.cpp b/src/core/tileset.cpp index 0ad43d1a..dc3bbd65 100644 --- a/src/core/tileset.cpp +++ b/src/core/tileset.cpp @@ -249,12 +249,10 @@ QList Tileset::getPalette(int paletteId, Tileset *primaryTileset, Tileset return paletteTable; } -bool Tileset::appendToHeaders(QString root, QString friendlyName, bool usingAsm) { - QString headersFile = root + "/" + (usingAsm ? projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm) - : projectConfig.getFilePath(ProjectFilePath::tilesets_headers)); - QFile file(headersFile); +bool Tileset::appendToHeaders(const QString &filepath, const QString &friendlyName, bool usingAsm) { + QFile file(filepath); if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) { - logError(QString("Could not write to file \"%1\"").arg(headersFile)); + logError(QString("Could not write to file \"%1\"").arg(filepath)); return false; } QString isSecondaryStr = this->is_secondary ? "TRUE" : "FALSE"; @@ -294,12 +292,10 @@ bool Tileset::appendToHeaders(QString root, QString friendlyName, bool usingAsm) return true; } -bool Tileset::appendToGraphics(QString root, QString friendlyName, bool usingAsm) { - QString graphicsFile = root + "/" + (usingAsm ? projectConfig.getFilePath(ProjectFilePath::tilesets_graphics_asm) - : projectConfig.getFilePath(ProjectFilePath::tilesets_graphics)); - QFile file(graphicsFile); +bool Tileset::appendToGraphics(const QString &filepath, const QString &friendlyName, bool usingAsm) { + QFile file(filepath); if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) { - logError(QString("Could not write to file \"%1\"").arg(graphicsFile)); + logError(QString("Could not write to file \"%1\"").arg(filepath)); return false; } @@ -332,12 +328,10 @@ bool Tileset::appendToGraphics(QString root, QString friendlyName, bool usingAsm return true; } -bool Tileset::appendToMetatiles(QString root, QString friendlyName, bool usingAsm) { - QString metatileFile = root + "/" + (usingAsm ? projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles_asm) - : projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles)); - QFile file(metatileFile); +bool Tileset::appendToMetatiles(const QString &filepath, const QString &friendlyName, bool usingAsm) { + QFile file(filepath); if (!file.open(QIODevice::WriteOnly | QIODevice::Append)) { - logError(QString("Could not write to file \"%1\"").arg(metatileFile)); + logError(QString("Could not write to file \"%1\"").arg(filepath)); return false; } diff --git a/src/project.cpp b/src/project.cpp index 0e845048..bf43143e 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -138,7 +138,9 @@ void Project::resetFileCache() { projectConfig.getFilePath(ProjectFilePath::global_fieldmap), }; for (const auto &path : filepaths) { - this->parser.cacheFile(path); + if (this->parser.cacheFile(path)) { + watchFile(path); + } } } @@ -218,6 +220,7 @@ QSet Project::getTopLevelMapFields() const { bool Project::readMapJson(const QString &mapName, QJsonDocument * out) { const QString mapFilepath = QString("%1%2/map.json").arg(projectConfig.getFilePath(ProjectFilePath::data_map_folders)).arg(mapName); + watchFile(mapFilepath); QString error; if (!parser.tryParseJsonFile(out, mapFilepath, &error)) { logError(QString("Failed to read map data from '%1': %2").arg(mapFilepath).arg(error)); @@ -488,7 +491,7 @@ bool Project::readMapLayouts() { clearMapLayouts(); const QString layoutsFilepath = projectConfig.getFilePath(ProjectFilePath::json_layouts); - fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(layoutsFilepath)); + watchFile(layoutsFilepath); QJsonDocument layoutsDoc; QString error; if (!parser.tryParseJsonFile(&layoutsDoc, layoutsFilepath, &error)) { @@ -642,11 +645,26 @@ bool Project::saveMapLayouts() { return true; } -void Project::ignoreWatchedFileTemporarily(QString filepath) { +void Project::watchFile(const QString &filename) { + this->fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(filename)); +} + +void Project::watchFiles(const QStringList &filenames) { + for (const auto &filename : filenames) + watchFile(filename); +} + +void Project::ignoreWatchedFileTemporarily(const QString &filepath) { // Ignore any file-change events for this filepath for the next 5 seconds. this->modifiedFileTimestamps.insert(filepath, QDateTime::currentMSecsSinceEpoch() + 5000); } +void Project::ignoreWatchedFilesTemporarily(const QStringList &filepaths) { + for (const auto &filepath : filepaths) { + ignoreWatchedFileTemporarily(filepath); + } +} + void Project::recordFileChange(const QString &filepath) { if (this->modifiedFiles.contains(filepath)) { // We already recorded a change to this file @@ -1257,6 +1275,8 @@ bool Project::saveMap(Map *map, bool skipLayout) { // Custom header fields. OrderedJson::append(&mapObj, map->customAttributes()); + ignoreWatchedFileTemporarily(mapFilepath); + OrderedJson mapJson(mapObj); OrderedJsonDoc jsonDoc(&mapJson); jsonDoc.dump(&mapFile); @@ -1456,12 +1476,25 @@ Tileset *Project::createNewTileset(QString name, bool secondary, bool checkerboa labelList->insert(i, tileset->name); this->tilesetLabelsOrdered.append(tileset->name); + // Append to tileset specific files. // TODO: Ideally we wouldn't save new Tilesets immediately - // Append to tileset specific files. Strip prefix from name to get base name for use in other symbols. - name.remove(0, prefix.length()); - tileset->appendToHeaders(this->root, name, this->usingAsmTilesets); - tileset->appendToGraphics(this->root, name, this->usingAsmTilesets); - tileset->appendToMetatiles(this->root, name, this->usingAsmTilesets); + QString headersFilepath = this->root + "/"; + QString graphicsFilepath = this->root + "/"; + QString metatilesFilepath = this->root + "/"; + if (this->usingAsmTilesets) { + headersFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm)); + graphicsFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_graphics_asm)); + metatilesFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles_asm)); + } else { + headersFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_headers)); + graphicsFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_graphics)); + metatilesFilepath.append(projectConfig.getFilePath(ProjectFilePath::tilesets_metatiles)); + } + ignoreWatchedFilesTemporarily({headersFilepath, graphicsFilepath, metatilesFilepath}); + name.remove(0, prefix.length()); // Strip prefix from name to get base name for use in other symbols. + tileset->appendToHeaders(headersFilepath, name, this->usingAsmTilesets); + tileset->appendToGraphics(graphicsFilepath, name, this->usingAsmTilesets); + tileset->appendToMetatiles(metatilesFilepath, name, this->usingAsmTilesets); tileset->save(); @@ -1485,7 +1518,7 @@ bool Project::readTilesetMetatileLabels() { unusedMetatileLabels.clear(); QString metatileLabelsFilename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_labels); - fileWatcher.addPath(root + "/" + metatileLabelsFilename); + watchFile(metatileLabelsFilename); const QSet regexList = {QString("\\b%1").arg(projectConfig.getIdentifier(ProjectIdentifier::define_metatile_label_prefix))}; const auto defines = parser.readCDefinesByRegex(metatileLabelsFilename, regexList); @@ -1593,7 +1626,7 @@ bool Project::readWildMonData() { const QString encounterRateFile = projectConfig.getFilePath(ProjectFilePath::wild_encounter); const QString maxEncounterRateName = projectConfig.getIdentifier(ProjectIdentifier::define_max_encounter_rate); - fileWatcher.addPath(QString("%1/%2").arg(root).arg(encounterRateFile)); + watchFile(encounterRateFile); auto defines = parser.readCDefinesByName(encounterRateFile, {maxEncounterRateName}); if (defines.contains(maxEncounterRateName)) this->maxEncounterRate = defines.value(maxEncounterRateName)/16; @@ -1602,8 +1635,7 @@ bool Project::readWildMonData() { const QString levelRangeFile = projectConfig.getFilePath(ProjectFilePath::constants_pokemon); const QString minLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_min_level); const QString maxLevelName = projectConfig.getIdentifier(ProjectIdentifier::define_max_level); - - fileWatcher.addPath(QString("%1/%2").arg(root).arg(levelRangeFile)); + watchFile(levelRangeFile); defines = parser.readCDefinesByName(levelRangeFile, {minLevelName, maxLevelName}); if (defines.contains(minLevelName)) this->pokemonMinLevel = defines.value(minLevelName); @@ -1615,7 +1647,7 @@ bool Project::readWildMonData() { // Read encounter data const QString wildMonJsonFilepath = projectConfig.getFilePath(ProjectFilePath::json_wild_encounters); - fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(wildMonJsonFilepath)); + watchFile(wildMonJsonFilepath); OrderedJson::object wildMonObj; QString error; @@ -1772,7 +1804,7 @@ bool Project::readMapGroups() { this->customMapGroupsData = QJsonObject(); const QString filepath = projectConfig.getFilePath(ProjectFilePath::json_map_groups); - fileWatcher.addPath(root + "/" + filepath); + watchFile(filepath); QJsonDocument mapGroupsDoc; QString error; if (!parser.tryParseJsonFile(&mapGroupsDoc, filepath, &error)) { @@ -2075,7 +2107,7 @@ bool Project::readTilesetLabels() { // If the tileset headers file is missing, the user may still have the old assembly format. this->usingAsmTilesets = true; QString asm_filename = projectConfig.getFilePath(ProjectFilePath::tilesets_headers_asm); - QString text = parser.readTextFile(this->root + "/" + asm_filename); + QString text = parser.loadTextFile(asm_filename); if (text.isEmpty()) { logError(QString("Failed to read tileset labels from '%1' or '%2'.").arg(filename).arg(asm_filename)); return false; @@ -2122,7 +2154,7 @@ bool Project::readFieldmapProperties() { const QString mapOffsetHeightName = projectConfig.getIdentifier(ProjectIdentifier::define_map_offset_height); const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_fieldmap); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); const auto defines = parser.readCDefinesByName(filename, { numTilesPrimaryName, numTilesTotalName, numMetatilesPrimaryName, @@ -2226,8 +2258,7 @@ bool Project::readFieldmapMasks() { const QString behaviorMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_behavior); const QString layerTypeMaskName = projectConfig.getIdentifier(ProjectIdentifier::define_mask_layer); - const QString globalFieldmap = projectConfig.getFilePath(ProjectFilePath::global_fieldmap); - fileWatcher.addPath(root + "/" + globalFieldmap); + const QString globalFieldmap = projectConfig.getFilePath(ProjectFilePath::global_fieldmap); // File already being watched const auto defines = parser.readCDefinesByName(globalFieldmap, { metatileIdMaskName, collisionMaskName, elevationMaskName, @@ -2282,7 +2313,7 @@ bool Project::readFieldmapMasks() { const QString layerTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_layer); const QString encounterTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_encounter); const QString terrainTypeTableName = projectConfig.getIdentifier(ProjectIdentifier::define_attribute_terrain); - fileWatcher.addPath(root + "/" + srcFieldmap); + watchFile(srcFieldmap); bool ok; // Read terrain type mask @@ -2360,7 +2391,7 @@ bool Project::readRegionMapSections() { logError(QString("Failed to read region map sections from '%1': %2").arg(filepath).arg(error)); return false; } - fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(filepath)); + watchFile(filepath); QJsonObject mapSectionsGlobalObj = doc.object(); QJsonArray mapSections = mapSectionsGlobalObj.take("map_sections").toArray(); @@ -2524,7 +2555,7 @@ bool Project::readHealLocations() { logError(QString("Failed to read heal locations from '%1': %2").arg(filepath).arg(error)); return false; } - fileWatcher.addPath(QString("%1/%2").arg(this->root).arg(filepath)); + watchFile(filepath); QJsonObject healLocationsObj = doc.object(); QJsonArray healLocations = healLocationsObj.take("heal_locations").toArray(); @@ -2547,7 +2578,7 @@ bool Project::readHealLocations() { bool Project::readItemNames() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_items); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->itemNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_items)}, &error); if (!error.isEmpty()) @@ -2557,7 +2588,7 @@ bool Project::readItemNames() { bool Project::readFlagNames() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_flags); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->flagNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_flags)}, &error); if (!error.isEmpty()) @@ -2567,7 +2598,7 @@ bool Project::readFlagNames() { bool Project::readVarNames() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_vars); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->varNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_vars)}, &error); if (!error.isEmpty()) @@ -2577,7 +2608,7 @@ bool Project::readVarNames() { bool Project::readMovementTypes() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_event_movement); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->movementTypes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_movement_types)}, &error); if (!error.isEmpty()) @@ -2587,7 +2618,7 @@ bool Project::readMovementTypes() { bool Project::readInitialFacingDirections() { QString filename = projectConfig.getFilePath(ProjectFilePath::initial_facing_table); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->facingDirections = parser.readNamedIndexCArray(filename, projectConfig.getIdentifier(ProjectIdentifier::symbol_facing_directions), &error); if (!error.isEmpty()) @@ -2597,7 +2628,7 @@ bool Project::readInitialFacingDirections() { bool Project::readMapTypes() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); - fileWatcher.addPath(root + "/" + filename); + // File already being watched QString error; this->mapTypes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_map_types)}, &error); if (!error.isEmpty()) @@ -2607,7 +2638,7 @@ bool Project::readMapTypes() { bool Project::readMapBattleScenes() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_map_types); - fileWatcher.addPath(root + "/" + filename); + // File already being watched QString error; this->mapBattleScenes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_battle_scenes)}, &error); if (!error.isEmpty()) @@ -2617,7 +2648,7 @@ bool Project::readMapBattleScenes() { bool Project::readWeatherNames() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->weatherNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_weather)}, &error); if (!error.isEmpty()) @@ -2630,7 +2661,7 @@ bool Project::readCoordEventWeatherNames() { return true; const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_weather); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->coordEventWeatherNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_coord_event_weather)}, &error); if (!error.isEmpty()) @@ -2643,7 +2674,7 @@ bool Project::readSecretBaseIds() { return true; const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_secret_bases); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->secretBaseIds = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_secret_bases)}, &error); if (!error.isEmpty()) @@ -2653,7 +2684,7 @@ bool Project::readSecretBaseIds() { bool Project::readBgEventFacingDirections() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_event_bg); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->bgEventFacingDirections = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_sign_facing_directions)}, &error); if (!error.isEmpty()) @@ -2663,7 +2694,7 @@ bool Project::readBgEventFacingDirections() { bool Project::readTrainerTypes() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_trainer_types); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->trainerTypes = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_trainer_types)}, &error); if (!error.isEmpty()) @@ -2676,7 +2707,7 @@ bool Project::readMetatileBehaviors() { this->metatileBehaviorMapInverse.clear(); QString filename = projectConfig.getFilePath(ProjectFilePath::constants_metatile_behaviors); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; const auto defines = parser.readCDefinesByRegex(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_behaviors)}, &error); if (defines.isEmpty() && projectConfig.metatileBehaviorMask) { @@ -2698,7 +2729,7 @@ bool Project::readMetatileBehaviors() { bool Project::readSongNames() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_songs); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; this->songNames = parser.readCDefineNames(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_music)}, &error); if (!error.isEmpty()) @@ -2713,7 +2744,7 @@ bool Project::readSongNames() { bool Project::readObjEventGfxConstants() { QString filename = projectConfig.getFilePath(ProjectFilePath::constants_obj_events); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); QString error; const auto defines = parser.readCDefinesByRegex(filename, {projectConfig.getIdentifier(ProjectIdentifier::regex_obj_event_gfx)}, &error); if (!error.isEmpty()) @@ -2729,7 +2760,7 @@ bool Project::readObjEventGfxConstants() { bool Project::readMiscellaneousConstants() { const QString filename = projectConfig.getFilePath(ProjectFilePath::constants_global); const QString maxObjectEventsName = projectConfig.getIdentifier(ProjectIdentifier::define_obj_event_count); - fileWatcher.addPath(root + "/" + filename); + watchFile(filename); const auto defines = parser.readCDefinesByName(filename, {maxObjectEventsName}); this->maxObjectEvents = 64; // Default value @@ -2856,7 +2887,7 @@ bool Project::readEventGraphics() { const QString gfxInfoFilepath = projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx_info); const QString picTablesFilepath = projectConfig.getFilePath(ProjectFilePath::data_obj_event_pic_tables); const QString gfxFilepath = projectConfig.getFilePath(ProjectFilePath::data_obj_event_gfx); - fileWatcher.addPaths({pointersFilepath, gfxInfoFilepath, picTablesFilepath, gfxFilepath}); + watchFiles({pointersFilepath, gfxInfoFilepath, picTablesFilepath, gfxFilepath}); // Read the table mapping OBJ_EVENT_GFX constants to the names of pointers to data about their graphics. const QString pointersName = projectConfig.getIdentifier(ProjectIdentifier::symbol_obj_event_gfx_pointers); @@ -3057,14 +3088,14 @@ bool Project::readSpeciesIconPaths() { // Read map of species constants to icon names const QString srcfilename = projectConfig.getFilePath(ProjectFilePath::pokemon_icon_table); - fileWatcher.addPath(this->root + "/" + srcfilename); + watchFile(srcfilename); const QString tableName = projectConfig.getIdentifier(ProjectIdentifier::symbol_pokemon_icon_table); const QMap monIconNames = parser.readNamedIndexCArray(srcfilename, tableName); // Read species constants. If this fails we can get them from the icon table (but we shouldn't rely on it). const QString speciesPrefix = projectConfig.getIdentifier(ProjectIdentifier::define_species_prefix); const QString constantsFilename = projectConfig.getFilePath(ProjectFilePath::constants_species); - fileWatcher.addPath(this->root + "/" + constantsFilename); + watchFile(constantsFilename); this->speciesNames = parser.readCDefineNames(constantsFilename, {QString("\\b%1").arg(speciesPrefix)}); if (this->speciesNames.isEmpty()) { this->speciesNames = monIconNames.keys(); @@ -3077,7 +3108,7 @@ bool Project::readSpeciesIconPaths() { // do this on request in Project::getDefaultSpeciesIconPath. if (!monIconNames.isEmpty()) { const QString iconGraphicsFile = projectConfig.getFilePath(ProjectFilePath::data_pokemon_gfx); - fileWatcher.addPath(this->root + "/" + iconGraphicsFile); + watchFile(iconGraphicsFile); QMap iconNameToFilepath = parser.readCIncbinMulti(iconGraphicsFile); for (auto i = monIconNames.constBegin(); i != monIconNames.constEnd(); i++) {