52 lines
1.4 KiB
C++
52 lines
1.4 KiB
C++
#pragma once
|
||
|
||
#include "domain/Project.h"
|
||
|
||
#include <QHash>
|
||
#include <QObject>
|
||
#include <QSet>
|
||
#include <QString>
|
||
#include <QTimer>
|
||
|
||
#include <atomic>
|
||
#include <mutex>
|
||
|
||
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<QString, Project::Entity> m_pendingEntities;
|
||
QHash<QString, Project::Animation> m_pendingAnimations;
|
||
|
||
std::atomic<int> m_outstandingDrains{0};
|
||
};
|
||
|
||
} // namespace core::persistence
|
||
|