DYTSrouce/src/workspace/WorkSpaceXMLParse.cpp
2025-11-12 23:02:32 +08:00

246 lines
8.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "workspace/WorkSpaceXMLParse.h"
#include "workspace/WorkSpace.h"
#include "entities/EntitiesManager.h"
#include "workspace/Timestep.h"
#include "common/SpdLogger.h"
#include "workspace/WorkSpaceManager.h"
#include "utils/StringUtils.h"
WorkSpaceXMLParse::WorkSpaceXMLParse(WorkSpace* workspace, QObject* parent) noexcept
: QObject(parent)
, workSpace_(workspace) {
}
bool WorkSpaceXMLParse::Save(const QString& path) {
path_ = path;
return false;
}
bool WorkSpaceXMLParse::ParseScene(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("element is nullptr");
return false;
}
const tinyxml2::XMLAttribute* current = element->FirstAttribute();
bool flag = false;
while (nullptr != current) {
const char* eleName = current->Name();
if (0 == strcmp(eleName, "name")) {
const char* name = current->Value();
workSpace_->SetName(name);
flag = true;
} else if (0 == strcmp(eleName, "describe")) {
const char* value = current->Value();
workSpace_->SetDescribe(value);
flag = true;
} else if (0 == strcmp(eleName, "uuid")) {
const char* value = current->Value();
workSpace_->SetUUid(value);
flag = true;
} else if (0 == strcmp(eleName, "viewpoint")) {
const char* value = current->Value();
workSpace_->SetHomeViewpoint(StringUtils::StringToViewpoint("home", value));
flag = true;
}
current = current->Next();
}
return flag;
}
bool WorkSpaceXMLParse::ParseTimestep(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("element is nullptr");
return false;
}
// 确保存在 Timestep 实例
workSpace_->EnsureTimestep();
Timestep* t = workSpace_->GetTimestep();
if (!t) {
return false;
}
// 解析属性manual(0/1)、start、end、step
int manualFlag = 0;
element->QueryIntAttribute("manual", &manualFlag);
double start = 0.0;
double end = 0.0;
double step = 0.0;
double speed = 0.0;
bool hasStart = (element->QueryDoubleAttribute("start", &start) == tinyxml2::XML_SUCCESS);
bool hasEnd = (element->QueryDoubleAttribute("end", &end) == tinyxml2::XML_SUCCESS);
bool hasStep = (element->QueryDoubleAttribute("step", &step) == tinyxml2::XML_SUCCESS);
bool hasSpeed = (element->QueryDoubleAttribute("speed", &speed) == tinyxml2::XML_SUCCESS);
if (hasSpeed) {
t->SetSpeed(speed);
}
if (hasStep) {
t->SetStep(step);
}
// 若标记为手动或具有完整的 start/end则设置手动范围否则按数据最大时间设置边界
if (manualFlag != 0 || (hasStart && hasEnd)) {
t->SetManualRange(hasStart ? start : 0.0, hasEnd ? end : 0.0);
} else if (hasEnd) {
t->SetDataMaxTime(end);
}
return true;
}
bool WorkSpaceXMLParse::ParseLamp(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("element is nullptr");
return false;
}
const char* path = element->Attribute("path");
if (nullptr == path) {
LOG_WARN("element not has path");
return false;
}
return workSpace_->SetLampPath(path);
}
bool WorkSpaceXMLParse::ParseCommond(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("commond element is nullptr");
return false;
}
const char* path = element->Attribute("path");
if (nullptr == path) {
LOG_WARN("commond element not has path");
return false;
}
// Set the command file path using the filename stored in XML
workSpace_->commondPath_ = path;
return true;
}
bool WorkSpaceXMLParse::ParseFiles(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("element is nullptr");
return false;
}
// 首先处理新的Chart元素结构
const tinyxml2::XMLElement* chartElement = element->FirstChildElement("Chart");
while (nullptr != chartElement) {
// 创建FileEntryCurve对象来解析Chart数据
auto curveEntry = CreateEmptyFileEntryCurve();
if (curveEntry && curveEntry->ParseFiles(chartElement)) {
// 添加解析后的FileEntry到workspace
workSpace_->SetFileEntry(curveEntry, false);
}
chartElement = chartElement->NextSiblingElement("Chart");
}
// 保持向后兼容处理旧的type元素结构
const tinyxml2::XMLElement* typeElement = element->FirstChildElement("type");
while (nullptr != typeElement) {
const char* name = typeElement->Attribute("name");
int count = 0;
typeElement->QueryIntAttribute("count", &count);
if (nullptr != name && count > 0) {
QString typeName = QString::fromLocal8Bit(name);
// Create FileEntry objects and call their ParseFiles method
FileEntryType enumType;
if (FileEntryTypeFromString(name, enumType)) {
const tinyxml2::XMLElement* chartElement = typeElement->FirstChildElement("chart");
while (nullptr != chartElement) {
auto fileEntry = CreateEmptyFileEntry(enumType); // Create empty FileEntry for XML parsing
if (fileEntry) {
// Call the FileEntry's ParseFiles method to parse detailed data
if (fileEntry->ParseFiles(chartElement)) {
// Add the parsed FileEntry to workspace
workSpace_->SetFileEntry(fileEntry, false);
}
}
chartElement = chartElement->NextSiblingElement();
}
// Create FileEntry objects for this type
//for (int i = 0; i < count; ++i) {
// auto fileEntry = CreateEmptyFileEntry(enumType); // Create empty FileEntry for XML parsing
// if (fileEntry) {
// // Call the FileEntry's ParseFiles method to parse detailed data
// if (fileEntry->ParseFiles(typeElement)) {
// // Add the parsed FileEntry to workspace
// workSpace_->SetFileEntry(fileEntry, false);
// }
// }
//}
// Also set file entry count for backward compatibility
workSpace_->SetFileEntryCount(enumType, count);
}
}
typeElement = typeElement->NextSiblingElement("type");
}
return true;
}
bool WorkSpaceXMLParse::ParseEntities(const tinyxml2::XMLElement* element) {
if (nullptr == element) {
LOG_WARN("element is nullptr");
return false;
}
const char* eleName = element->Name();
if (0 == strcmp(eleName, "entities")) {
return EntitiesManager::Get().Parse(element, workSpace_);
}
LOG_WARN("element not has entities");
return false;
}
bool WorkSpaceXMLParse::Load(const QString& dyt) {
std::string path = dyt.toLocal8Bit().constData();
LOG_INFO("load path:{}", path);
tinyxml2::XMLDocument xmlDocument;
tinyxml2::XMLError error = xmlDocument.LoadFile(path.c_str());
if (tinyxml2::XMLError::XML_SUCCESS != error) {
LOG_INFO("load feiled:{}", static_cast<int>(error));
return false;
}
const tinyxml2::XMLElement* root = xmlDocument.RootElement();
if (!ParseScene(root)) {
return false;
}
const tinyxml2::XMLElement* xmlElement = root->FirstChildElement();
while (nullptr != xmlElement) {
const char* name = xmlElement->Name();
if (0 == strcmp(name, "entities")) {
ParseEntities(xmlElement);
} else if (0 == strcmp(name, "timestep")) {
ParseTimestep(xmlElement);
} else if (0 == strcmp(name, "lamp")) {
ParseLamp(xmlElement);
} else if (0 == strcmp(name, "commond")) {
ParseCommond(xmlElement);
} else if (0 == strcmp(name, "files")) {
ParseFiles(xmlElement);
}
xmlElement = xmlElement->NextSiblingElement();
}
return true;
}