DYTSrouce/src/workspace/PresetModelConfigParser.cpp
2025-11-02 00:02:20 +08:00

204 lines
6.4 KiB
C++

#include "workspace/PresetModelConfigParser.h"
#include <QDir>
#include <QFileInfo>
#include "xml/tinyxml2.h"
#include "common/SpdLogger.h"
template<> PresetModelConfigParser* Singleton<PresetModelConfigParser>::instance_ = nullptr;
PresetModelConfigParser::PresetModelConfigParser(QObject* parent)
: QObject(parent) {
}
PresetModelConfigParser::~PresetModelConfigParser() {
}
bool PresetModelConfigParser::LoadAllConfigs(const QString& configDir) {
Clear();
QDir dir(configDir);
if (!dir.exists()) {
SetError(QString("Config directory does not exist: %1").arg(configDir));
LOG_WARN("Preset config directory does not exist: {}", configDir.toStdString());
return false;
}
// Get all XML files
QStringList filters;
filters << "*.xml";
QFileInfoList fileList = dir.entryInfoList(filters, QDir::Files);
if (fileList.isEmpty()) {
SetError(QString("No XML files found in config directory: %1").arg(configDir));
LOG_WARN("No XML files found in preset config directory: {}", configDir.toStdString());
return false;
}
bool hasSuccess = false;
for (const QFileInfo& fileInfo : fileList) {
if (LoadConfig(fileInfo.absoluteFilePath())) {
hasSuccess = true;
LOG_INFO("Successfully loaded preset config: {}", fileInfo.fileName().toStdString());
} else {
LOG_WARN("Failed to load preset config: {}", fileInfo.fileName().toStdString());
}
}
return hasSuccess;
}
bool PresetModelConfigParser::LoadConfig(const QString& filePath)
{
if (!QFileInfo::exists(filePath)) {
SetError(QString("Config file does not exist: %1").arg(filePath));
return false;
}
return ParseXmlFile(filePath);
}
bool PresetModelConfigParser::ParseXmlFile(const QString& filePath)
{
tinyxml2::XMLDocument doc;
tinyxml2::XMLError error = doc.LoadFile(filePath.toLocal8Bit().constData());
if (error != tinyxml2::XML_SUCCESS) {
SetError(QString("Failed to parse XML file: %1, error code: %2").arg(filePath).arg(static_cast<int>(error)));
return false;
}
const tinyxml2::XMLElement* root = doc.RootElement();
if (!root) {
SetError(QString("XML file has no root element: %1").arg(filePath));
return false;
}
if (strcmp(root->Name(), "modelCategory") != 0) {
SetError(QString("XML file root element is not modelCategory: %1").arg(filePath));
return false;
}
ModelCategory category;
const char* name = root->Attribute("name");
const char* displayName = root->Attribute("displayName");
const char* icon = root->Attribute("icon");
if (!name) {
SetError(QString("modelCategory missing name attribute: %1").arg(filePath));
return false;
}
category.name = QString::fromUtf8(name);
category.displayName = displayName ? QString::fromUtf8(displayName) : category.name;
category.icon = icon ? QString::fromUtf8(icon) : "";
// Read model list
const tinyxml2::XMLElement* modelElement = root->FirstChildElement("model");
while (modelElement) {
ModelInfo model;
const char* modelName = modelElement->Attribute("name");
const char* modelDisplayName = modelElement->Attribute("displayName");
const char* description = modelElement->Attribute("description");
const char* meshFile = modelElement->Attribute("meshFile");
const char* modelIcon = modelElement->Attribute("icon");
const char* label = modelElement->Attribute("label");
const char* enabled = modelElement->Attribute("enabled");
// Entity registration attributes
const char* entityType = modelElement->Attribute("entityType");
const char* entityClass = modelElement->Attribute("entityClass");
const char* requiredComponents = modelElement->Attribute("requiredComponents");
if (!modelName) {
LOG_WARN("Model element missing name attribute in file: {}", filePath.toStdString());
modelElement = modelElement->NextSiblingElement("model");
continue;
}
model.name = QString::fromUtf8(modelName);
model.displayName = modelDisplayName ? QString::fromUtf8(modelDisplayName) : model.name;
model.description = description ? QString::fromUtf8(description) : "";
model.meshFile = meshFile ? QString::fromUtf8(meshFile) : "";
model.icon = modelIcon ? QString::fromUtf8(modelIcon) : "";
model.useLabel = label ? (strcmp(label, "true") == 0) : true;
model.enabled = enabled ? (strcmp(enabled, "true") == 0) : true;
category.models.append(model);
modelElement = modelElement->NextSiblingElement("model");
}
// Store category data
m_categories[category.name] = category;
return true;
}
QStringList PresetModelConfigParser::GetModelNames(const QString& categoryName) const
{
QStringList names;
if (m_categories.contains(categoryName)) {
const ModelCategory& category = m_categories[categoryName];
for (const ModelInfo& model : category.models) {
if (model.enabled) {
names.append(model.name);
}
}
}
return names;
}
QStringList PresetModelConfigParser::GetCategoryNames() const
{
return m_categories.keys();
}
ModelCategory PresetModelConfigParser::GetCategory(const QString& categoryName) const
{
if (m_categories.contains(categoryName)) {
return m_categories[categoryName];
}
return ModelCategory();
}
ModelInfo PresetModelConfigParser::GetModelInfo(const QString& categoryName, const QString& modelName, bool* success) const {
if (m_categories.contains(categoryName)) {
const ModelCategory& category = m_categories[categoryName];
for (const ModelInfo& model : category.models) {
if (model.name == modelName) {
if (success) *success = true;
return model;
}
}
}
if (success) *success = false;
return ModelInfo();
}
bool PresetModelConfigParser::HasData() const
{
return !m_categories.isEmpty();
}
void PresetModelConfigParser::Clear()
{
m_categories.clear();
m_lastError.clear();
}
QString PresetModelConfigParser::GetLastError() const
{
return m_lastError;
}
void PresetModelConfigParser::SetError(const QString& error)
{
m_lastError = error;
}