Files
RCiRoot e3f7733316 V20260829-2.6.1
完成框架目录和模块重构;新增核心、单例、工具、加密及框架 SDK;统一任务、相机和 RPC 接口,并增加离线检测、相机标定、备份恢复、版本管理、崩溃守护和心跳监控功能。
2026-09-20 16:01:09 +08:00

76 lines
2.6 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include <eui_tools/export.h>
#include <QObject>
#include <QString>
#include <nlohmannJson.hpp>
#include <condition_variable>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <mutex>
#include <thread>
#include <vector>
// DeferredJsonWriter:euiJson 的附属延迟保存器。把高频的 JSON 全量写盘合并为固定 1s 窗口
// (从第一次请求起算),窗口内同一路径只保留最后一次的取数函数;窗口到期后在属主线程调用
// 取数函数拿到最新值,再交给后台 IO 线程执行 euiJson::write,写盘失败通过 writeFailed
// 信号异步上报,避免高频全量写盘占用界面线程。
//
// 使用约定:
// - 窗口计时依赖属主线程的事件循环;程序退出前必须调用 flushAll() 落盘。
// - flushAll() 需在属主线程调用(退出路径均在主线程);其他线程调用时会投递
// 到属主线程执行,此时要求属主线程事件循环仍在运行。
class EUI_TOOLS_API DeferredJsonWriter : public QObject {
Q_OBJECT
public:
using Json = nlohmann::ordered_json;
// 延迟保存的取数函数:窗口到期/落盘时在属主线程调用,返回最新配置值。
using ValueProvider = std::function<Json()>;
explicit DeferredJsonWriter(QObject* parent = nullptr);
~DeferredJsonWriter() override;
DeferredJsonWriter(const DeferredJsonWriter&) = delete;
DeferredJsonWriter& operator=(const DeferredJsonWriter&) = delete;
// 请求延迟保存:窗口内同一路径只保留最后一次 provider,窗口到期后取最新值写盘。
void requestSave(const std::filesystem::path& jsonPath, ValueProvider provider);
// 立即取消窗口并同步写完全部待写内容,返回是否全部写盘成功。
bool flushAll();
signals:
void writeFailed(const QString& jsonPath, const QString& error);
private:
struct PendingSave {
std::filesystem::path path;
ValueProvider provider;
};
struct WriteTask {
std::filesystem::path path;
Json json;
};
void onWindowTimeout(uint64_t generation);
void enqueueTasks(std::vector<PendingSave>&& pending);
void workerLoop();
bool waitIdle(int timeoutMs);
static constexpr int kWindowMs = 1000;
static constexpr int kFlushTimeoutMs = 30000;
std::thread ioThread_;
std::mutex mutex_;
std::condition_variable condition_;
std::vector<PendingSave> pending_;
std::vector<WriteTask> tasks_;
bool windowPending_ = false;
bool stopRequested_ = false;
int inflight_ = 0;
uint64_t windowGeneration_ = 0;
};