#ifndef NMPEBIRESULTPLAYBACKCONTROLLER_H #define NMPEBIRESULTPLAYBACKCONTROLLER_H #include "nmSubWxs_global.h" #include #include #include #include class QTimer; class nmPebiResultSceneController; /** * @brief 管理结果属性选择、压力帧请求和回放定时器。 * * SceneController 是已渲染属性和帧的唯一真实来源。本控制器只保存播放状态、 * 速度、循环偏好、最后压力帧和已观察的快照 ID,不持有任何 VTK 对象。 */ class NM_SUB_WXS_EXPORT nmPebiResultPlaybackController : public QObject { Q_OBJECT public: /** @brief 回放速度的合法下限和窗口默认值,单位均为步/秒。 */ enum { MinimumPlaybackSpeed = 1, DefaultPlaybackSpeed = 5 }; /** @param pSceneController 非所有权指针,必须比本控制器生命周期更长。 */ explicit nmPebiResultPlaybackController( nmPebiResultSceneController* pSceneController, QObject* pParent = nullptr); /** @brief 停止定时器;QTimer 随 QObject 子对象树自动销毁。 */ virtual ~nmPebiResultPlaybackController(); /** * @brief 按 Scene 成功绑定序号同步场景状态。 * * 新快照和无快照会停止播放;同快照普通重同步保留有效播放状态。 */ void synchronizeFromScene(); /** @brief 暂停后选择属性;动态压力恢复最后一次成功帧,失败返回 false。 */ bool selectProperty(const QString& sPropertyId); /** @brief 暂停后请求当前动态属性切换到指定零基帧,失败返回 false。 */ bool selectFrame(int nFrameIndex); /** @brief 暂停并请求当前动态属性的第一帧。 */ bool selectFirstFrame(); /** @brief 暂停并请求当前动态属性的上一帧。 */ bool selectPreviousFrame(); /** @brief 暂停并请求当前动态属性的下一帧。 */ bool selectNextFrame(); /** @brief 暂停并请求当前动态属性的末帧。 */ bool selectLastFrame(); /** @brief 在播放和暂停之间切换;末帧开始播放时先提交第 0 帧。 */ bool togglePlayback(); /** @brief 只停止 Timer,不改变 Scene 当前帧。 */ void pause(); /** * @brief 事务式提交回放速度和循环偏好。 * @note 速度非法时两个设置均保持不变。 */ bool setPlaybackSettings(int nStepsPerSecond, bool bLoopEnabled); /** @brief 返回 Scene 是否仍有完整可渲染快照。 */ bool isAvailable() const; /** @brief 返回控制器最近一次同步到的快照 ID。 */ QString getObservedSnapshotId() const; /** @brief 返回最近一次普通 Scene 同步观察到的成功绑定序号。 */ quint64 getObservedBindingRevision() const; /** @brief 直接转发 Scene 中按 Catalog 排序的可用属性 ID。 */ QStringList getAvailablePropertyIds() const; /** @brief 直接转发 Scene 已成功渲染的当前属性 ID。 */ QString getCurrentPropertyId() const; /** @brief 直接转发 Scene 已成功渲染的当前零基帧。 */ int getCurrentFrameIndex() const; /** @brief 直接查询 Scene 中指定属性是否为动态属性。 */ bool isPropertyTimeDependent(const QString& sPropertyId) const; /** @brief 直接查询 Scene 中指定属性的帧数。 */ int getPropertyFrameCount(const QString& sPropertyId) const; /** @brief 返回指定动态帧的求解时间,单位固定为小时。 */ bool getPropertyTimeAt(const QString& sPropertyId, int nFrameIndex, double& dTime) const; /** @brief 返回 Scene 当前属性是否为动态属性。 */ bool isCurrentPropertyTimeDependent() const; /** @brief 返回 Scene 当前属性的帧数。 */ int getCurrentPropertyFrameCount() const; /** @brief 返回同一快照内最后一次成功提交的压力帧记忆。 */ int getLastPressureFrameIndex() const; /** @brief 返回当前窗口回放速度,单位为步/秒。 */ int getPlaybackSpeed() const; /** @brief 返回当前速度对应的整数毫秒间隔。 */ int getPlaybackIntervalMilliseconds() const; /** @brief 返回当前窗口是否启用循环播放。 */ bool isLoopEnabled() const; /** @brief 返回 Timer 和播放标志是否同时处于运行状态。 */ bool isPlaying() const; signals: /** @brief 任一可观察状态完成提交或完成外部同步后发出。 */ void stateChanged(); /** @brief 操作失败且状态已恢复到最后成功值后发出。 */ void operationFailed(const QString& sError); private slots: /** @brief 计算下一目标帧,Scene 成功提交后才更新压力帧记忆。 */ void onPlaybackTimeout(); private: Q_DISABLE_COPY(nmPebiResultPlaybackController) /** @brief 停止定时器但不发信号,供事务路径统一收尾。 */ bool stopTimerWithoutSignal(); /** @brief 同步快照身份;返回当前 Scene 是否仍有可用快照。 */ bool synchronizeSceneIdentity(); /** @brief 按固定顺序同步失败后的 Scene 状态并通知界面。 */ bool finishFailedOperation(const QString& sError); /** @brief 使用当前速度计算至少 1ms 的定时器间隔。 */ int calculatePlaybackInterval() const; /** @brief 已渲染属性和帧的唯一真实来源;本类不拥有。 */ nmPebiResultSceneController* m_pSceneController; /** @brief 驱动帧请求的 QObject 子对象,由本控制器自动销毁。 */ QTimer* m_pTimer; /** @brief 最近一次同步成功的 Snapshot ID,用于识别快照替换。 */ QString m_sObservedSnapshotId; /** @brief 最近一次普通 Scene 同步观察到的成功绑定序号。 */ quint64 m_nObservedBindingRevision; /** @brief 当前活动 Timer 启动时捕获的 Scene 成功绑定序号。 */ quint64 m_nPlaybackBindingRevision; /** @brief 同一快照内最后一次成功提交的 pressure 零基帧。 */ int m_nLastPressureFrameIndex; /** @brief 当前窗口播放速度,单位为步/秒。 */ int m_nStepsPerSecond; /** @brief 末帧之后是否回到第 0 帧。 */ bool m_bLoopEnabled; /** @brief 与 Timer 共同描述当前是否正在自动回放。 */ bool m_bPlaying; }; #endif // NMPEBIRESULTPLAYBACKCONTROLLER_H