DYTSrouce/src/workspace/Timestep.cpp

162 lines
4.6 KiB
C++
Raw Normal View History

2025-01-04 04:12:51 +00:00
#include "workspace/Timestep.h"
2025-11-10 15:19:13 +00:00
#include <algorithm>
2025-01-04 04:12:51 +00:00
#include <QFile>
#include <QTextStream>
#include "workspace/WorkSpace.h"
#include "common/RecourceHelper.h"
#include "common/SpdLogger.h"
Timestep::Timestep(const std::vector<double>& steps, const QString& path, WorkSpace* parent /*= nullptr*/) noexcept
: QObject((QObject*)parent)
, steps_(steps)
, path_(path)
, workSpace_(parent) {
maxTime_ = *steps_.rbegin();
2025-11-10 15:19:13 +00:00
// 初始化为 1.0x,如果列表中没有 1.0,则取最接近中间的默认索引
auto it = std::find(speedLevels_.begin(), speedLevels_.end(), 1.0);
speedIndex_ = it != speedLevels_.end() ? int(std::distance(speedLevels_.begin(), it)) : speedIndex_;
currentStep_ = speedLevels_[speedIndex_];
2025-01-04 04:12:51 +00:00
}
Timestep* Timestep::Load(const QString& path, WorkSpace* workSpace) {
const QString filePath = QString("%1/%2").arg(workSpace->GetDir()).arg(path);
2025-01-04 04:12:51 +00:00
LOG_INFO("Load timestep: {}", filePath.toStdString());
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
LOG_WARN("Cannot open file for reading: {}", file.errorString().toLocal8Bit().constData());
2025-01-04 04:12:51 +00:00
return nullptr;
}
QTextStream in(&file);
std::vector<double> numbers;
while (!in.atEnd()) {
QString line = in.readLine();
bool ok;
double value = line.toDouble(&ok);
if (ok) {
numbers.push_back(value);
} else {
LOG_WARN("Cannot open file for reading: {}", line.toStdString());
}
}
file.close();
Timestep* timestep = new Timestep(numbers, path, workSpace);
2025-01-04 04:12:51 +00:00
return timestep;
}
void Timestep::GetRange(double& minTime, double& maxTime, double& step) {
minTime = *steps_.begin();
maxTime = maxTime_;
step = currentStep_;
}
void Timestep::Update(double dt) {
if (playStatus_ != PlayStatus::PS_Started) {
return;
}
if (nullptr == workSpace_) {
LOG_WARN("workSpace_ is nullptr");
return;
}
double deltaTime = dt * currentStep_;
current_ += deltaTime;
workSpace_->OnFrame(deltaTime);
if (current_ >= maxTime_ && playStatus_ != PlayStatus::PS_Stoped) {
current_ = maxTime_;
Stop();
}
emit TimeChanged(current_);
}
bool Timestep::IsPause() {
return playStatus_ == PlayStatus::PS_Suspended && playStatus_ != PlayStatus::PS_Started;
}
bool Timestep::IsStoped() {
return playStatus_ == PlayStatus::PS_Stoped;
}
void Timestep::Start() {
LOG_INFO("enter");
playStatus_ = PlayStatus::PS_Started;
current_ = 0.0;
if (nullptr == workSpace_) {
LOG_WARN("workSpace_ is nullptr");
return;
}
workSpace_->Begin();
2025-11-10 15:19:13 +00:00
// 重置速度为 1x 并通知 UI
auto it = std::find(speedLevels_.begin(), speedLevels_.end(), 1.0);
speedIndex_ = it != speedLevels_.end() ? int(std::distance(speedLevels_.begin(), it)) : speedIndex_;
currentStep_ = speedLevels_[speedIndex_];
emit StepChanged(currentStep_);
2025-01-04 04:12:51 +00:00
emit StatusChanged((int)playStatus_);
}
void Timestep::Resume() {
LOG_INFO("enter");
if (PlayStatus::PS_Suspended != playStatus_) {
LOG_WARN("play status is not suspended");
return;
}
playStatus_ = PlayStatus::PS_Started;
emit StatusChanged((int)playStatus_);
}
void Timestep::Pause() {
LOG_INFO("enter");
if (PlayStatus::PS_Started == playStatus_) {
playStatus_ = PlayStatus::PS_Suspended;
} else if (PlayStatus::PS_Suspended == playStatus_) {
playStatus_ = PlayStatus::PS_Started;
}
emit StatusChanged((int)playStatus_);
}
void Timestep::Stop() {
LOG_INFO("enter");
current_ = maxTime_;
playStatus_ = PlayStatus::PS_Stoped;
if (nullptr == workSpace_) {
LOG_WARN("workSpace_ is nullptr");
return;
}
workSpace_->End();
2025-11-10 15:19:13 +00:00
// 停止时也恢复为 1x避免停后再次播放仍是异常倍率
auto it = std::find(speedLevels_.begin(), speedLevels_.end(), 1.0);
speedIndex_ = it != speedLevels_.end() ? int(std::distance(speedLevels_.begin(), it)) : speedIndex_;
currentStep_ = speedLevels_[speedIndex_];
emit StepChanged(currentStep_);
2025-01-04 04:12:51 +00:00
emit StatusChanged((int)playStatus_);
}
void Timestep::Up() {
2025-11-10 15:19:13 +00:00
// 提升到下一个倍率(封顶)
if (speedIndex_ < int(speedLevels_.size()) - 1) {
++speedIndex_;
}
currentStep_ = speedLevels_[speedIndex_];
emit StepChanged(currentStep_);
2025-01-04 04:12:51 +00:00
}
void Timestep::Down() {
2025-11-10 15:19:13 +00:00
// 降到上一个倍率(保底)
if (speedIndex_ > 0) {
--speedIndex_;
}
currentStep_ = speedLevels_[speedIndex_];
emit StepChanged(currentStep_);
2025-01-04 04:12:51 +00:00
}