#pragma once #include "domain/Project.h" #include #include #include #include #include #include #include namespace core::persistence { /// 后台写盘队列:合并/防抖,避免 UI 线程同步写文件。 /// 目前以“实体/动画为单位”合并;后续会细化到块级 dirty bits(meta/anim/intro/png...)。 class AsyncProjectWriter final : public QObject { Q_OBJECT public: explicit AsyncProjectWriter(QObject* parent = nullptr); void setProjectDir(const QString& projectDirAbs); /// enqueue:线程安全由调用方保证在 UI 线程调用(本类内部用 singleShot 防抖到 writer 线程)。 void requestWriteEntity(const Project::Entity& entity); void requestWriteAnimation(const Project::Animation& animation); /// 阻塞等待:用于 close/退出时确保落盘完成。 void flushBlocking(int timeoutMs = 30000); signals: void entityWriteFailed(const QString& entityId); void animationWriteFailed(const QString& animationId); private: void scheduleDrain(); QString m_projectDir; QTimer* m_debounce = nullptr; std::mutex m_mutex; // 最新快照:同 id 多次更新只写最后一次 QHash m_pendingEntities; QHash m_pendingAnimations; std::atomic m_outstandingDrains{0}; }; } // namespace core::persistence