From 81a5298e14dd99de3afcaf57f231cdecdacedf97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=B0=E4=BB=94?= Date: Fri, 3 Jul 2026 14:11:39 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BD=AE=E8=83=8E=E6=A3=80=E6=B5=8B=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E7=AE=97=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TireHolePoseApp/TireHolePoseApp.pro | 2 +- App/TireHolePose/TireHolePoseApp/Version.h | 2 +- App/TireHolePose/TireHolePoseApp/Version.md | 4 + AppUtils/AppCommon/Inc/BasePresenter.h | 5 +- AppUtils/AppCommon/Inc/DebugDataSaver.h | 63 +++-- AppUtils/AppCommon/Src/BasePresenter.cpp | 49 +++- AppUtils/AppCommon/Src/DebugDataSaver.cpp | 257 ++++++++++++++---- 7 files changed, 289 insertions(+), 93 deletions(-) diff --git a/App/TireHolePose/TireHolePoseApp/TireHolePoseApp.pro b/App/TireHolePose/TireHolePoseApp/TireHolePoseApp.pro index 4f6ae678..12b17eb5 100644 --- a/App/TireHolePose/TireHolePoseApp/TireHolePoseApp.pro +++ b/App/TireHolePose/TireHolePoseApp/TireHolePoseApp.pro @@ -165,7 +165,7 @@ else:win32:CONFIG(debug, debug|release): { } else:unix:!macx: { LIBS += -L$$PWD/../../../AppAlgo/workpieceHolePositioning/Arm/aarch64 -lworkpieceHolePositioning -lbaseAlgorithm - LIBS += -L$$PWD/../../../SDK/OpenCV320/Arm/aarch64 -lopencv_core -lopencv_imgproc -lopencv_highgui + LIBS += -L$$PWD/../../../SDK/OpenCV320/Arm/aarch64 -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs } # 添加libmodbus依赖 diff --git a/App/TireHolePose/TireHolePoseApp/Version.h b/App/TireHolePose/TireHolePoseApp/Version.h index 0f3cec6b..6b61051d 100644 --- a/App/TireHolePose/TireHolePoseApp/Version.h +++ b/App/TireHolePose/TireHolePoseApp/Version.h @@ -2,7 +2,7 @@ #define TIREHOLEPOSE_VERSION_H #define TIREHOLEPOSE_APP_NAME "轮胎孔定位" -#define TIREHOLEPOSE_VERSION_STRING "1.0.1" +#define TIREHOLEPOSE_VERSION_STRING "1.0.2" #define TIREHOLEPOSE_BUILD_STRING "1" #define TIREHOLEPOSE_FULL_VERSION_STRING "V" TIREHOLEPOSE_VERSION_STRING "_" TIREHOLEPOSE_BUILD_STRING diff --git a/App/TireHolePose/TireHolePoseApp/Version.md b/App/TireHolePose/TireHolePoseApp/Version.md index f1b7c80b..cdc3641c 100644 --- a/App/TireHolePose/TireHolePoseApp/Version.md +++ b/App/TireHolePose/TireHolePoseApp/Version.md @@ -1,3 +1,7 @@ +# 1.0.1 2026-07-03 +## build_1 +1. 更新算法 + # 1.0.1 2026-06-26 ## build_1 1. 更新算法 diff --git a/AppUtils/AppCommon/Inc/BasePresenter.h b/AppUtils/AppCommon/Inc/BasePresenter.h index 75a298b1..1d55c205 100644 --- a/AppUtils/AppCommon/Inc/BasePresenter.h +++ b/AppUtils/AppCommon/Inc/BasePresenter.h @@ -441,9 +441,8 @@ protected: * * @param debugParam 调试参数 */ - void SetDebugParam(const VrDebugParam& debugParam) { - m_debugParam = debugParam; - } + void SetDebugParam(const VrDebugParam& debugParam); + void SetDebugDataSaveQueueSize(int maxQueueSize); /** * @brief 保存点云文件时附加在设备名后的标签(虚函数,子类可选择重写) diff --git a/AppUtils/AppCommon/Inc/DebugDataSaver.h b/AppUtils/AppCommon/Inc/DebugDataSaver.h index 3b876266..a36381d8 100644 --- a/AppUtils/AppCommon/Inc/DebugDataSaver.h +++ b/AppUtils/AppCommon/Inc/DebugDataSaver.h @@ -1,14 +1,17 @@ #ifndef DEBUG_DATA_SAVER_H #define DEBUG_DATA_SAVER_H -#include -#include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "VZNL_Types.h" class DebugDataSaver @@ -17,49 +20,56 @@ public: explicit DebugDataSaver(int maxThreads = 4); ~DebugDataSaver(); - // 异步保存点云数据(内部深拷贝数据,不阻塞调用线程) - // timestamp: 检测时刻的时间戳,格式 YYYYMMDD_HHmmss - // 调用方需在持有数据锁时调用,DeepCopyData 会在调用线程完成深拷贝 void SaveAsync(const std::string& basePath, const std::string& timestamp, const std::vector>& data, const std::string& deviceName = ""); - // 停止所有工作线程(等待队列中任务完成后退出) void Stop(); - // 设置 PointCloud 目录最大总大小(字节)。超过后保存前会循环删除最早的文件。默认 10GB void SetMaxStorageSize(int64_t bytes) { m_maxStorageSize = bytes; } + void SetMaxQueueSize(int maxTasks); + void PrepareStorageCache(const std::string& basePath); private: struct SaveTask { + std::string basePath; std::string filePath; std::string deviceName; std::vector> data; }; + struct StorageFileInfo { + std::string path; + int64_t size = 0; + int64_t lastModifiedMSecs = 0; + }; + + struct StorageCache { + bool initialized = false; + int64_t totalSize = 0; + std::vector files; + }; + void WorkerThread(); - // 深拷贝检测数据(含原始指针数组的完整拷贝) static std::vector> DeepCopyData( const std::vector>& src); - - // 释放深拷贝的数据 static void FreeData(std::vector>& data); - // 生成带日期目录的完整保存路径: basePath/YYYYMMDD/pointcloud[_deviceName]_YYYYMMDD_HHmmss_NNN.txt - // timestamp: 检测时刻的时间戳,格式 YYYYMMDD_HHmmss - // deviceName: 设备名称(为空时不包含在文件名中) - std::string GenerateSavePath(const std::string& basePath, const std::string& timestamp, const std::string& deviceName = ""); + std::string GenerateSavePath(const std::string& basePath, + const std::string& timestamp, + const std::string& deviceName = ""); - // 确保 basePath 总大小不超过 m_maxStorageSize,超过时循环删除最早的文件 - // basePath: SaveAsync 传入的根目录(不含日期子目录) void EnsureStorageLimit(const std::string& basePath); + void EnsureStorageLimitLocked(const std::string& basePath, StorageCache& cache); + void BuildStorageCacheLocked(const std::string& basePath, StorageCache& cache); + void AddFileToCacheLocked(StorageCache& cache, const StorageFileInfo& fileInfo); + void RecordSavedFile(const std::string& basePath, const std::string& filePath); - // 统计 rootPath 下(含子目录)所有 .txt 文件的总大小(字节) + static bool RemoveFileFromCache(StorageCache& cache, const std::string& filePath); + static bool IsOlderFile(const StorageFileInfo& lhs, const StorageFileInfo& rhs); static int64_t ComputeDirSize(const std::string& rootPath); - - // 查找 rootPath 下(含子目录)按修改时间排序最早的 .txt 文件,找不到返回空串 static std::string FindOldestFile(const std::string& rootPath); int m_maxThreads; @@ -68,10 +78,11 @@ private: std::mutex m_queueMutex; std::condition_variable m_queueCondition; std::atomic m_running; + std::atomic m_maxQueueSize{10}; - // 磁盘空间维护:多个 worker 共享,必须串行 std::mutex m_diskSpaceMutex; - std::atomic m_maxStorageSize{10LL * 1024 * 1024 * 1024}; // 默认 10GB + std::atomic m_maxStorageSize{10LL * 1024 * 1024 * 1024}; + std::map m_storageCaches; }; #endif // DEBUG_DATA_SAVER_H diff --git a/AppUtils/AppCommon/Src/BasePresenter.cpp b/AppUtils/AppCommon/Src/BasePresenter.cpp index fb56b142..b6fbcc08 100644 --- a/AppUtils/AppCommon/Src/BasePresenter.cpp +++ b/AppUtils/AppCommon/Src/BasePresenter.cpp @@ -10,6 +10,28 @@ #include "PathManager.h" #include "IYModbusTCPServer.h" +namespace { + +QString ResolveDebugOutputPath(const VrDebugParam& debugParam) +{ + if (debugParam.debugOutputPath.empty()) { + return QCoreApplication::applicationDirPath() + "/debug"; + } + return QString::fromStdString(debugParam.debugOutputPath); +} + +QString EnsureDebugOutputPath(const VrDebugParam& debugParam) +{ + QString outputPath = ResolveDebugOutputPath(debugParam); + QDir dir(outputPath); + if (!dir.exists()) { + dir.mkpath("."); + } + return outputPath; +} + +} // namespace + BasePresenter::BasePresenter(QObject *parent) : QObject(parent) , m_currentCameraIndex(0) @@ -366,6 +388,21 @@ void BasePresenter::SetWorkStatus(WorkStatus status) } // ============ InitCamera 完整实现 ============ +void BasePresenter::SetDebugParam(const VrDebugParam& debugParam) +{ + m_debugParam = debugParam; + + if (m_debugParam.enableDebug && m_debugParam.savePointCloud) { + QString outputPath = EnsureDebugOutputPath(m_debugParam); + m_debugDataSaver.PrepareStorageCache(outputPath.toStdString()); + } +} + +void BasePresenter::SetDebugDataSaveQueueSize(int maxQueueSize) +{ + m_debugDataSaver.SetMaxQueueSize(maxQueueSize); +} + int BasePresenter::InitCamera(std::vector& cameraList, bool bRGB, bool bSwing) { LOG_INFO("[BasePresenter] InitCamera\n"); @@ -618,19 +655,9 @@ int BasePresenter::DetectTask() // 2. 调试模式 - 异步保存点云数据(不持 m_detectionDataMutex 锁,深拷贝在 SaveAsync 内进行) if (debugParam.enableDebug && debugParam.savePointCloud) { // 确定输出路径 - QString outputPath; - if (debugParam.debugOutputPath.empty()) { - outputPath = QCoreApplication::applicationDirPath() + "/debug"; - } else { - outputPath = QString::fromStdString(debugParam.debugOutputPath); - } + QString outputPath = EnsureDebugOutputPath(debugParam); // 确保输出根目录存在 - QDir dir(outputPath); - if (!dir.exists()) { - dir.mkpath("."); - } - // 在检测时刻生成时间戳(毫秒精度),文件名将形如 {设备名}_YYYYMMDD_HHmmsszzz.txt std::string timestamp = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmsszzz").toStdString(); diff --git a/AppUtils/AppCommon/Src/DebugDataSaver.cpp b/AppUtils/AppCommon/Src/DebugDataSaver.cpp index 1e338c2e..60c9f9bc 100644 --- a/AppUtils/AppCommon/Src/DebugDataSaver.cpp +++ b/AppUtils/AppCommon/Src/DebugDataSaver.cpp @@ -1,32 +1,48 @@ #include "DebugDataSaver.h" #include "LaserDataLoader.h" -#include "VrLog.h" #include "VrError.h" +#include "VrLog.h" + #include +#include #include #include #include #include -#include #include + +#include #include +#include namespace { -// 获取当前应用名(不含扩展名),用于构造 debug 子目录前缀 + QString AppName() { QString name = QFileInfo(QCoreApplication::applicationFilePath()).baseName(); - if (name.isEmpty()) name = QStringLiteral("app"); + if (name.isEmpty()) { + name = QStringLiteral("app"); + } return name; } -// 子目录前缀:{appName}_PointCloud_,仅匹配此前缀的子目录会被统计/清理 QString SubDirPrefix() { return AppName() + QStringLiteral("_PointCloud_"); } + +std::string NormalizeBasePath(const std::string& basePath) +{ + return QDir(QString::fromStdString(basePath)).absolutePath().toStdString(); } +std::string NormalizeFilePath(const std::string& filePath) +{ + return QFileInfo(QString::fromStdString(filePath)).absoluteFilePath().toStdString(); +} + +} // namespace + DebugDataSaver::DebugDataSaver(int maxThreads) : m_maxThreads(std::max(1, std::min(maxThreads, 4))) , m_running(true) @@ -34,7 +50,7 @@ DebugDataSaver::DebugDataSaver(int maxThreads) for (int i = 0; i < m_maxThreads; ++i) { m_workers.emplace_back(&DebugDataSaver::WorkerThread, this); } - LOG_INFO("[DebugDataSaver] 已启动 %d 个存储线程\n", m_maxThreads); + LOG_INFO("[DebugDataSaver] started %d storage threads\n", m_maxThreads); } DebugDataSaver::~DebugDataSaver() @@ -57,29 +73,68 @@ void DebugDataSaver::Stop() } m_workers.clear(); - // 释放队列中未处理的任务 + std::lock_guard lock(m_queueMutex); while (!m_taskQueue.empty()) { FreeData(m_taskQueue.front().data); m_taskQueue.pop(); } - LOG_INFO("[DebugDataSaver] 已停止\n"); + LOG_INFO("[DebugDataSaver] stopped\n"); } -void DebugDataSaver::SaveAsync(const std::string& basePath, const std::string& timestamp, const std::vector>& data, const std::string& deviceName) +void DebugDataSaver::SetMaxQueueSize(int maxTasks) { - if (data.empty() || !m_running) return; + if (maxTasks < 1) { + maxTasks = 1; + } + m_maxQueueSize = maxTasks; +} + +void DebugDataSaver::PrepareStorageCache(const std::string& basePath) +{ + std::lock_guard lock(m_diskSpaceMutex); + StorageCache& cache = m_storageCaches[NormalizeBasePath(basePath)]; + if (!cache.initialized) { + BuildStorageCacheLocked(basePath, cache); + LOG_INFO("[DebugDataSaver] storage cache ready: %s, files=%zu, size=%lld\n", + basePath.c_str(), cache.files.size(), static_cast(cache.totalSize)); + } + EnsureStorageLimitLocked(basePath, cache); +} + +void DebugDataSaver::SaveAsync(const std::string& basePath, + const std::string& timestamp, + const std::vector>& data, + const std::string& deviceName) +{ + if (data.empty() || !m_running.load()) { + return; + } + + const int maxQueueSize = m_maxQueueSize.load(); + { + std::lock_guard lock(m_queueMutex); + if (static_cast(m_taskQueue.size()) >= maxQueueSize) { + LOG_WARNING("[DebugDataSaver] save queue full (%zu/%d), skip point cloud save: %s\n", + m_taskQueue.size(), maxQueueSize, deviceName.c_str()); + return; + } + } SaveTask task; + task.basePath = basePath; task.deviceName = deviceName; task.filePath = GenerateSavePath(basePath, timestamp, deviceName); task.data = DeepCopyData(data); - // 在入队前清理超限文件,避免任务堆积时磁盘瞬间打满 - EnsureStorageLimit(basePath); - { std::lock_guard lock(m_queueMutex); + if (static_cast(m_taskQueue.size()) >= maxQueueSize) { + LOG_WARNING("[DebugDataSaver] save queue full after copy (%zu/%d), skip point cloud save: %s\n", + m_taskQueue.size(), maxQueueSize, deviceName.c_str()); + FreeData(task.data); + return; + } m_taskQueue.push(std::move(task)); } m_queueCondition.notify_one(); @@ -94,10 +149,10 @@ void DebugDataSaver::WorkerThread() { std::unique_lock lock(m_queueMutex); m_queueCondition.wait(lock, [this] { - return !m_taskQueue.empty() || !m_running; + return !m_taskQueue.empty() || !m_running.load(); }); - if (!m_running && m_taskQueue.empty()) { + if (!m_running.load() && m_taskQueue.empty()) { break; } if (m_taskQueue.empty()) { @@ -116,9 +171,10 @@ void DebugDataSaver::WorkerThread() int result = dataLoader.SaveLaserScanData(task.filePath, task.data, lineNum, scanSpeed, maxTimeStamp, clockPerSecond); if (result == SUCCESS) { - LOG_INFO("[DebugDataSaver] 保存成功: %s (%d行)\n", task.filePath.c_str(), lineNum); + RecordSavedFile(task.basePath, task.filePath); + LOG_INFO("[DebugDataSaver] saved: %s (%d lines)\n", task.filePath.c_str(), lineNum); } else { - LOG_ERROR("[DebugDataSaver] 保存失败: %s, 错误: %s\n", task.filePath.c_str(), dataLoader.GetLastError().c_str()); + LOG_ERROR("[DebugDataSaver] save failed: %s, error: %s\n", task.filePath.c_str(), dataLoader.GetLastError().c_str()); } FreeData(task.data); @@ -180,9 +236,10 @@ void DebugDataSaver::FreeData(std::vector lock(m_diskSpaceMutex); + StorageCache& cache = m_storageCaches[NormalizeBasePath(basePath)]; + if (!cache.initialized) { + BuildStorageCacheLocked(basePath, cache); + } + EnsureStorageLimitLocked(basePath, cache); +} + +void DebugDataSaver::EnsureStorageLimitLocked(const std::string& basePath, StorageCache& cache) +{ + Q_UNUSED(basePath); const int64_t limit = m_maxStorageSize.load(); - if (limit <= 0) return; + if (limit <= 0) { + return; + } - int64_t totalSize = ComputeDirSize(basePath); const QString prefix = SubDirPrefix(); + while (cache.totalSize > limit && !cache.files.empty()) { + StorageFileInfo oldest = cache.files.front(); + cache.files.erase(cache.files.begin()); - // 循环删除最早的文件,直到目录总大小 <= limit - while (totalSize > limit) { - std::string oldest = FindOldestFile(basePath); - if (oldest.empty()) { - LOG_WARNING("[DebugDataSaver] 目录大小 %lld 超过上限 %lld,但无可删除文件\n", - static_cast(totalSize), static_cast(limit)); - break; - } - - QFileInfo info(QString::fromStdString(oldest)); - qint64 fileSize = info.size(); + QString filePath = QString::fromStdString(oldest.path); + QFileInfo info(filePath); QString parentPath = info.absolutePath(); + int64_t fileSize = oldest.size; - if (!QFile::remove(QString::fromStdString(oldest))) { - LOG_ERROR("[DebugDataSaver] 删除失败: %s\n", oldest.c_str()); + if (QFileInfo::exists(filePath) && !QFile::remove(filePath)) { + cache.files.insert(cache.files.begin(), oldest); + LOG_ERROR("[DebugDataSaver] delete failed: %s\n", oldest.path.c_str()); break; } - LOG_INFO("[DebugDataSaver] 磁盘超限,删除最早文件: %s (%lld 字节)\n", - oldest.c_str(), static_cast(fileSize)); - totalSize -= fileSize; + cache.totalSize -= fileSize; + if (cache.totalSize < 0) { + cache.totalSize = 0; + } + + LOG_INFO("[DebugDataSaver] storage limit exceeded, delete oldest file: %s (%lld bytes)\n", + oldest.path.c_str(), static_cast(fileSize)); - // 父目录若已为空且名字匹配 {appName}_PointCloud_* 前缀,连同目录一起回收 QDir parentDir(parentPath); const QString parentName = parentDir.dirName(); if (parentName.startsWith(prefix) && parentDir.isEmpty()) { parentDir.cdUp(); if (parentDir.rmdir(parentName)) { - LOG_INFO("[DebugDataSaver] 已移除空目录: %s\n", parentPath.toStdString().c_str()); + LOG_INFO("[DebugDataSaver] removed empty directory: %s\n", parentPath.toStdString().c_str()); } } } } +void DebugDataSaver::BuildStorageCacheLocked(const std::string& basePath, StorageCache& cache) +{ + cache.files.clear(); + cache.totalSize = 0; + + QDir rootDir(QString::fromStdString(basePath)); + if (rootDir.exists()) { + const QString prefix = SubDirPrefix(); + const QStringList subDirs = rootDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + for (const QString& name : subDirs) { + if (!name.startsWith(prefix)) { + continue; + } + QString subPath = rootDir.absoluteFilePath(name); + QDirIterator it(subPath, QStringList() << "*.txt", QDir::Files, QDirIterator::Subdirectories); + while (it.hasNext()) { + it.next(); + QFileInfo info = it.fileInfo(); + StorageFileInfo fileInfo; + fileInfo.path = info.absoluteFilePath().toStdString(); + fileInfo.size = info.size(); + fileInfo.lastModifiedMSecs = info.lastModified().toMSecsSinceEpoch(); + cache.totalSize += fileInfo.size; + cache.files.push_back(fileInfo); + } + } + } + + std::sort(cache.files.begin(), cache.files.end(), DebugDataSaver::IsOlderFile); + cache.initialized = true; +} + +void DebugDataSaver::AddFileToCacheLocked(StorageCache& cache, const StorageFileInfo& fileInfo) +{ + RemoveFileFromCache(cache, fileInfo.path); + auto it = std::lower_bound(cache.files.begin(), cache.files.end(), fileInfo, DebugDataSaver::IsOlderFile); + cache.files.insert(it, fileInfo); + cache.totalSize += fileInfo.size; +} + +void DebugDataSaver::RecordSavedFile(const std::string& basePath, const std::string& filePath) +{ + std::lock_guard lock(m_diskSpaceMutex); + StorageCache& cache = m_storageCaches[NormalizeBasePath(basePath)]; + if (!cache.initialized) { + BuildStorageCacheLocked(basePath, cache); + } + + std::string normalizedFilePath = NormalizeFilePath(filePath); + QFileInfo info(QString::fromStdString(normalizedFilePath)); + if (info.exists() && info.isFile()) { + StorageFileInfo fileInfo; + fileInfo.path = normalizedFilePath; + fileInfo.size = info.size(); + fileInfo.lastModifiedMSecs = info.lastModified().toMSecsSinceEpoch(); + AddFileToCacheLocked(cache, fileInfo); + } + + EnsureStorageLimitLocked(basePath, cache); +} + +bool DebugDataSaver::RemoveFileFromCache(StorageCache& cache, const std::string& filePath) +{ + auto it = std::find_if(cache.files.begin(), cache.files.end(), [&filePath](const StorageFileInfo& item) { + return item.path == filePath; + }); + if (it == cache.files.end()) { + return false; + } + + cache.totalSize -= it->size; + if (cache.totalSize < 0) { + cache.totalSize = 0; + } + cache.files.erase(it); + return true; +} + +bool DebugDataSaver::IsOlderFile(const StorageFileInfo& lhs, const StorageFileInfo& rhs) +{ + if (lhs.lastModifiedMSecs == rhs.lastModifiedMSecs) { + return lhs.path < rhs.path; + } + return lhs.lastModifiedMSecs < rhs.lastModifiedMSecs; +} + int64_t DebugDataSaver::ComputeDirSize(const std::string& rootPath) { - QString root = QString::fromStdString(rootPath); - QDir rootDir(root); - if (!rootDir.exists()) return 0; + QDir rootDir(QString::fromStdString(rootPath)); + if (!rootDir.exists()) { + return 0; + } const QString prefix = SubDirPrefix(); int64_t total = 0; - - // 只统计匹配 {appName}_debug_* 模式的子目录,避免误判 basePath 下其他内容 const QStringList subDirs = rootDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); for (const QString& name : subDirs) { - if (!name.startsWith(prefix)) continue; + if (!name.startsWith(prefix)) { + continue; + } QString subPath = rootDir.absoluteFilePath(name); QDirIterator it(subPath, QStringList() << "*.txt", QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { @@ -271,9 +423,10 @@ int64_t DebugDataSaver::ComputeDirSize(const std::string& rootPath) std::string DebugDataSaver::FindOldestFile(const std::string& rootPath) { - QString root = QString::fromStdString(rootPath); - QDir rootDir(root); - if (!rootDir.exists()) return std::string(); + QDir rootDir(QString::fromStdString(rootPath)); + if (!rootDir.exists()) { + return std::string(); + } const QString prefix = SubDirPrefix(); QString oldestPath; @@ -282,7 +435,9 @@ std::string DebugDataSaver::FindOldestFile(const std::string& rootPath) const QStringList subDirs = rootDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); for (const QString& name : subDirs) { - if (!name.startsWith(prefix)) continue; + if (!name.startsWith(prefix)) { + continue; + } QString subPath = rootDir.absoluteFilePath(name); QDirIterator it(subPath, QStringList() << "*.txt", QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) {