204 lines
6.4 KiB
C++
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;
|
|
} |