DYTSrouce/src/workspace/WorkSpace.cpp
2025-10-13 08:20:53 +08:00

396 lines
11 KiB
C++

#include "workspace/WorkSpace.h"
#include <QUUID>
#include <QFileInfo>
#include <QDir>
#include "workspace/WorkSpaceXMLParse.h"
#include "workspace/WorkSpaceXMLWrite.h"
#include "workspace/CommandManager.h"
#include "workspace/WorkSpaceItem.h"
#include "workspace/Timestep.h"
#include "workspace/LampStatus.h"
#include "xml/tinyxml2.h"
#include "common/SpdLogger.h"
#include "entities/Entity.h"
#include "utils/FileUtils.h"
#include <QProcess>
//#include "workspace/WorkSpaceItemGroup.h"
//#include "workspace/WorkSpaceRiverGroup.h"
//#include "workspace/WorkSpaceRiverNetGroup.h"
Q_DECLARE_METATYPE(WorkSpace*)
WorkSpace::WorkSpace(QObject* parent) noexcept
: QObject(parent) {
uuid_ = QUuid::createUuid().toString();
homeViewpoint_ = osgEarth::Viewpoint("home", 120.000000, 25.000000, 100.000000, -2.500000, -90.000000, 8200000.000000);
cmdMgr_ = std::make_unique<CommandManager>();
}
WorkSpace::WorkSpace(const QString& path, QObject* parent)
: QObject(parent)
, path_(path){
uuid_ = QUuid::createUuid().toString();
homeViewpoint_ = osgEarth::Viewpoint("home", 120.000000, 25.000000, 100.000000, -2.500000, -90.000000, 8200000.000000);
cmdMgr_ = std::make_unique<CommandManager>();
}
const QString WorkSpace::GetDir() const {
QFileInfo info(path_);
return info.absolutePath();
}
void WorkSpace::SetCommondFilePath(const QString& path) {
QFileInfo fileInfo(path);
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
LOG_INFO("copy commond file {}: {} to {}",
path.toLocal8Bit().data(),
dirPath.toLocal8Bit().data(),
sucess);
commondPath_ = fileInfo.fileName();
}
const QString WorkSpace::GetCommondFilePath() const {
QString path = QString("%1/%2").arg(GetDir(), commondPath_);
return path;
}
void WorkSpace::SetSimMatlab(const QString& path) {
QFileInfo fileInfo(path);
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
LOG_INFO("copy simmatlab file {}: {} to {}",
path.toLocal8Bit().data(),
dirPath.toLocal8Bit().data(),
sucess);
simMatlabPath_ = fileInfo.fileName();
}
const QString WorkSpace::GetSimMatlab() const {
QString path = QString("%1/%2").arg(GetDir(), simMatlabPath_);
return path;
}
void WorkSpace::SetWavePath(const QString& path)
{
QFileInfo fileInfo(path);
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
LOG_INFO("copy Wave file {}: {} to {}",
path.toLocal8Bit().data(),
dirPath.toLocal8Bit().data(),
sucess);
waveFile_ = fileInfo.fileName();
}
const QString WorkSpace::GetWavePath() const
{
QString path = QString("%1/%2").arg(GetDir(), waveFile_);
return path;
}
void WorkSpace::SetReportPath(const QString& path)
{
QFileInfo fileInfo(path);
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
LOG_INFO("copy Wave file {}: {} to {}",
path.toLocal8Bit().data(),
dirPath.toLocal8Bit().data(),
sucess);
reportFile_ = fileInfo.fileName();
}
const QString WorkSpace::GetReportPath() const
{
QString path = QString("%1/%2").arg(GetDir(), reportFile_);
return path;
}
void WorkSpace::SetRDPath(const QString& path)
{
QFileInfo fileInfo(path);
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
LOG_INFO("copy RD file {}: {} to {}",
path.toLocal8Bit().data(),
dirPath.toLocal8Bit().data(),
sucess);
rdFile_ = fileInfo.fileName();
}
std::vector<FileEntry> WorkSpace::GetFileEntries(FileEntryType type) const {
auto it = files_.find(type);
if (it == files_.end()) {
return {};
}
return it->second;
}
WorkSpace::FileEntryResult WorkSpace::CreateFileEntry(FileEntryType type) {
auto& vec = files_[type];
if (vec.size() >= 9) {
return FileEntryResult::LimitExceeded;
}
// push a placeholder; actual filename may be set elsewhere via SetWavePath/SetRDPath/etc
vec.push_back(FileEntry{ type, QString() });
++filesSeq_;
// Notify listeners (e.g., PropertyBrowser) to refresh workspace properties
emit FilesChanged(type);
return FileEntryResult::Ok;
}
bool WorkSpace::SetFileEntryCount(FileEntryType type, int count) {
if (count < 0) count = 0;
if (count > 9) count = 9;
auto& vec = files_[type];
if (static_cast<int>(vec.size()) == count) {
return true;
}
if (static_cast<int>(vec.size()) < count) {
int toAdd = count - static_cast<int>(vec.size());
for (int i = 0; i < toAdd; ++i) {
vec.push_back(FileEntry{ type, QString() });
}
} else {
vec.resize(count);
}
++filesSeq_;
emit FilesChanged(type);
return true;
}
bool WorkSpace::SetFileEntryPath(FileEntryType type, int index, const QString& path) {
auto& vec = files_[type];
if (index < 0 || index >= static_cast<int>(vec.size())) {
return false;
}
QFileInfo fileInfo(path);
if (!fileInfo.exists()) {
return false;
}
QString dirPath = QString("%1/%2").arg(GetDir(), fileInfo.fileName());
bool sucess = FileUtils::CopyFileToPath(path, dirPath, true);
LOG_INFO("copy grouped file {}: {} to {}",
path.toLocal8Bit().data(),
dirPath.toLocal8Bit().data(),
sucess);
if (!sucess) {
return false;
}
vec[index].fileName = fileInfo.fileName();
++filesSeq_;
emit FilesChanged(type);
return true;
}
QString WorkSpace::GetFileEntryAbsPath(FileEntryType type, int index) const {
auto it = files_.find(type);
if (it == files_.end()) {
return QString();
}
const auto& vec = it->second;
if (index < 0 || index >= static_cast<int>(vec.size())) {
return QString();
}
const QString& name = vec[index].fileName;
if (name.isEmpty()) {
return QString();
}
return QString("%1/%2").arg(GetDir(), name);
}
const QString WorkSpace::GetRDPath() const
{
QString path = QString("%1/%2").arg(GetDir(), rdFile_);
return path;
}
void WorkSpace::AddEntity(Entity* entity) {
if (nullptr == entity) {
LOG_WARN("entity is nullptr");
return;
}
LOG_INFO("add entity: {}", entity->GetName().toLocal8Bit().constData());
entities_.push_back(entity);
entity->SetWorkspace(this);
emit EntityAdded(entity);
}
void WorkSpace::RemoveEntity(Entity* entity) {
auto itor = std::find_if(entities_.begin(), entities_.end(),
[this, entity](const auto* item) { return item == entity; });
if (itor != entities_.end()) {
emit EntityRemoved(entity);
entities_.erase(itor);
}
}
bool WorkSpace::TrackEntity(Entity* entity) {
dyt_check(nullptr != entity);
if (trackedEntity_ == entity) {
LOG_INFO("entity already tracked: {}", entity->GetName().toStdString());
return true;
}
if (nullptr == scene_) {
LOG_WARN("scene is nullptr, cannot track entity: {}", entity->GetName().toStdString());
return false;
}
if (trackedEntity_ != entity) {
UntrackEntity();
}
trackedEntity_ = entity;
auto mt = entity->GetRootComponent()->GetMatrixTransform();
LOG_INFO("track entity: {}", entity->GetName().toStdString());
return scene_->TrackEntity(mt, true);
}
void WorkSpace::UntrackEntity() {
if (trackedEntity_ != nullptr) {
if (scene_ != nullptr) {
LOG_INFO("untrack entity: {}", trackedEntity_->GetName().toStdString());
auto mt = trackedEntity_->GetRootComponent()->GetMatrixTransform();
scene_->TrackEntity(mt, false);
}
}
trackedEntity_ = nullptr;
}
void WorkSpace::SetActiveScene(OEScene* scene) {
dyt_check(nullptr != scene);
scene_ = scene;
//osgEarth::Viewpoint vp;
//vp.name() = "home";
//vp.focalPoint()->set(scene->GetSrs(), -121.488, 46.2054, 0, osgEarth::AltitudeMode::ALTMODE_ABSOLUTE);
//vp.pitch() = -50.0;
//vp.range() = 100000;
//homeViewpoint_ = vp;
}
bool WorkSpace::SetTimestep(Timestep* timestep) {
if (!timestep) {
return false;
}
if (nullptr != timestep_ && timestep_ != timestep) {
timestep_->deleteLater();
}
timestep_ = timestep;
emit TimestepChanged(timestep_);
return true;
}
bool WorkSpace::SetTimestepPath(const QString& path) {
Timestep* timestep = Timestep::Load(path, this);
return SetTimestep(timestep);
}
bool WorkSpace::SetLampStatus(class LampStatus* lampStatus) {
if (!lampStatus) {
return false;
}
if (nullptr != lampStatus_ && lampStatus_ != lampStatus) {
lampStatus_->deleteLater();
}
lampStatus_ = lampStatus;
emit LampStatusChanged(lampStatus_);
return true;
}
bool WorkSpace::SetLampPath(const QString& path) {
LampStatus* timestep = LampStatus::Load(path, this);
return SetLampStatus(timestep);
}
bool WorkSpace::Save(const QString& path) {
path_ = path;
return Save();
}
bool WorkSpace::Save() {
WorkSpaceXMLWrite xmlWrite(this);
return xmlWrite.Save(path_);
}
bool WorkSpace::Load(const QString& dyt) {
if (leaded_) {
LOG_INFO("dyt {} loaded", dyt.toStdString());
return true;
}
LOG_INFO("dyt {} loading", dyt.toLocal8Bit().constData());
path_ = dyt;
WorkSpaceXMLParse parse(this);
bool success = parse.Load(dyt);
if (!success) {
path_ = "";
}
leaded_ = success;
return success;
}
void WorkSpace::Unlaod() {
if (!leaded_) {
LOG_INFO("dyt {} unloaded", name_.toStdString());
return;
}
while (!entities_.empty()) {
auto entity = entities_.front();
entity->Destory();
}
leaded_ = false;
}
void WorkSpace::Begin() {
for (auto item : entities_) {
item->Begin();
}
}
void WorkSpace::OnFrame(double dt) {
if (nullptr != lampStatus_) {
double current = timestep_->GetCurrent();
lampStatus_->OnFrame(current);
}
for (auto item : entities_) {
item->Update(dt);
}
}
void WorkSpace::End() {
for (auto item : entities_) {
item->End();
}
}
void WorkSpace::OnLoaded() {
if (nullptr != lampStatus_) {
emit LampStatusChanged(lampStatus_);
}
if (nullptr != timestep_) {
emit TimestepChanged(timestep_);
}
// Execute commands configured for onLoad
ExecuteCommands(CommandWhen::OnLoad);
}
void WorkSpace::ExecuteCommands(CommandWhen when) {
if (!cmdMgr_) {
cmdMgr_ = std::make_unique<CommandManager>();
}
cmdMgr_->Execute(this, when);
}