#include "XNServiceObject.h" #include "XNEventManager/XNEventManager.h" #include "XNFramework/XNFramework.h" #include "XNServiceObject_p.h" namespace XNSim { XNServiceObject::XNServiceObject() : XNObject(new XNServiceObjectPrivate()) { T_D(); d->_initialType = 0; } XNServiceObject::~XNServiceObject() {} XNServiceObject::XNServiceObject(PrivateType *p) : XNObject(p) {} const XN_STRING &XNServiceObject::GetVersion() { T_D(); return d->_sVersion; } const XN_STRING &XNServiceObject::GetDescription() { T_D(); return d->_sDescription; } const XN_STRING &XNServiceObject::GetAuthor() { T_D(); return d->_sAuthor; } const XN_STRING &XNServiceObject::GetXmlPath() { T_D(); return d->_sXmlPath; } const XNTimePoint &XNServiceObject::GetCreateTime() { T_D(); return d->_cCreateTime; } const XNTimePoint &XNServiceObject::GetChangeTime() { T_D(); return d->_cChangeTime; } void XNServiceObject::SetVersion(const XN_STRING &version) { T_D(); d->_sVersion = version; } void XNServiceObject::SetDescription(const XN_STRING &sDescription) { T_D(); d->_sDescription = sDescription; } void XNServiceObject::SetAuthor(const XN_STRING &sAuthor) { T_D(); d->_sAuthor = sAuthor; } void XNServiceObject::SetXmlPath(const XN_STRING &sXmlPath) { T_D(); d->_sXmlPath = sXmlPath; } void XNServiceObject::SetCreateTime(const XNTimePoint &cTime) { T_D(); d->_cCreateTime = cTime; } void XNServiceObject::SetChangeTime(const XNTimePoint &cTime) { T_D(); d->_cChangeTime = cTime; } XN_INT32 XNServiceObject::RegisterEventHandler(const XN_STRING &eventName, XNEventCallback callback, bool async, XNEvent::Priority priority) { // 注册事件处理器 T_D(); auto framework = GetFramework(); if (framework) { auto eventManager = framework->GetEventManager(); if (eventManager) { return eventManager->RegisterEventHandler(eventName, callback, GetUniqueId(), async, priority); } } return -1; } void XNServiceObject::TriggerEvent(const XN_STRING &eventName, const XN_ANY &eventData, bool forceAsync, XNEvent::Priority priority) { // 触发事件 T_D(); auto framework = GetFramework(); if (framework) { auto eventManager = framework->GetEventManager(); if (eventManager) { eventManager->TriggerEvent(eventName, eventData, forceAsync, priority); } } } XN_INT32 XNServiceObject::RegisterRTEventHandler(const XN_STRING &eventName, XNEventCallback callback) { return RegisterEventHandler(eventName, callback, true, XNEvent::Priority::RealTime); } void XNServiceObject::TriggerRTEvent(const XN_STRING &eventName, const XN_ANY &eventData) { TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime); } void XNServiceObject::SetInitializeType(XN_UINT32 initialType) { T_D(); d->_initialType = initialType; } void XNServiceObject::Initialize() { T_D(); if (d->_initialType == 0) { ParseXml(); } else { ParseConfig(); } } void XNServiceObject::ParseXml() { T_D(); XN_XMLDocument doc; if (LoadXmlFile(GetXmlPath(), doc) != 0) { LOG_WARNING("Failed to open the service configuration file: %1!", GetXmlPath()); return; } XN_XMLElement *rootNode = GetRootElement(doc); if (!rootNode) { LOG_WARNING("Invalid XML file format: %1!", GetXmlPath()); return; } XN_STRING serviceName = GetFirstChildElementText(rootNode, "Name"); if (serviceName != GetObjectName()) { LOG_WARNING( "The service name in the configuration file of service %1 is not " "consistent " "with the service name in the configuration file of service %2!", GetObjectName(), serviceName); return; } d->_sDescription = GetFirstChildElementText(rootNode, "Description"); d->_sAuthor = GetFirstChildElementText(rootNode, "Author"); d->_sVersion = GetFirstChildElementText(rootNode, "Version"); // 解析时间 XN_STRING createTimeStr = GetFirstChildElementText(rootNode, "CreateTime"); XN_STRING changeTimeStr = GetFirstChildElementText(rootNode, "ChangeTime"); d->_cCreateTime = parseISOTime(createTimeStr); d->_cChangeTime = parseISOTime(changeTimeStr); XN_XMLElement *nodeCmds = GetFirstChildElement(rootNode, "CommandList"); if (nodeCmds) { for (XN_XMLElement *nodeCmd = GetFirstChildElement(nodeCmds, "Command"); nodeCmd != nullptr; nodeCmd = GetNextSiblingElement(nodeCmd, "Command")) { XN_STRING cmdName = GetAttribute(nodeCmd, "Name"); XN_STRING cmdDescription = GetAttribute(nodeCmd, "Description"); XN_STRING cmdCall = GetAttribute(nodeCmd, "Call"); // TODO: 处理命令信息 } } } void XNServiceObject::ParseConfig() { T_D(); XN_STRINGLIST nameAndVersion = XNSplit(GetXmlPath(), ","); XN_STRING serviceName = nameAndVersion[0]; XN_STRING serviceVersion = nameAndVersion[1]; // 获取数据库路径 XN_STRING dbPath = getEnv("XNCore"); if (dbPath.empty()) { LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!"); return; } dbPath += "/database/XNSim.db"; // 打开数据库 XN_DB_PTR db = openDatabase(dbPath); if (db == nullptr) { LOG_ERROR("0x1016 打开数据库失败: %1", dbPath); return; } // 准备SQL语句 XN_STRING sql = "SELECT * FROM XNServiceVersion WHERE ClassName = ? AND Version = ?"; XN_DB_STMT_PTR stmt = prepareSql(db, sql); if (stmt == nullptr) { LOG_ERROR("0x1017 准备SQL语句失败: %1", sql); closeDatabase(db); return; } // 绑定参数 if (!bindText(stmt, 1, serviceName) || !bindText(stmt, 2, serviceVersion)) { LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db)); finalizeSql(stmt); closeDatabase(db); return; } // 执行查询 if (!stepSql(stmt)) { LOG_ERROR("0x1019 未找到服务名称为%1,版本号%2的记录", serviceName.c_str(), serviceVersion.c_str()); finalizeSql(stmt); closeDatabase(db); return; } d->_sDescription = getStringFromSqlite3(stmt, 5); d->_sAuthor = getStringFromSqlite3(stmt, 4); d->_sVersion = getStringFromSqlite3(stmt, 2); // 解析时间 XN_STRING createTimeStr = getStringFromSqlite3(stmt, 6); XN_STRING changeTimeStr = getStringFromSqlite3(stmt, 7); d->_cCreateTime = parseISOTime(createTimeStr); d->_cChangeTime = parseISOTime(changeTimeStr); // 读取服务命令列表 XN_STRING commandListStr = getStringFromSqlite3(stmt, 8); if (!commandListStr.empty()) { try { XN_JSON commandList = parseJson(commandListStr); if (commandList.is_array()) { for (const auto &cmd : commandList) { if (cmd.contains("Name") && cmd.contains("Description") && cmd.contains("Call")) { LOG_INFO("0x1021 服务命令: %1", cmd["Name"].get()); // TODO: 处理服务命令信息 // d->_commandList.emplace_back( // cmd["Name"].get(), // cmd["Description"].get(), // cmd["Call"].get() // ); } } } } catch (const std::exception &e) { LOG_WARNING("0x1020 解析服务命令列表失败: %1", e.what()); } } // 读取其他参数 XN_STRING otherParamsStr = getStringFromSqlite3(stmt, 9); if (!otherParamsStr.empty()) { try { d->_otherParams = parseJson(otherParamsStr); } catch (const std::exception &e) { LOG_WARNING("0x1020 解析其他参数失败: %1", e.what()); } } // 清理资源 finalizeSql(stmt); closeDatabase(db); } void XNServiceObject::PrepareForExecute() { T_D(); RegisterDDSParticipant(); } void XNServiceObject::RegisterDDSParticipant() { T_D(); // TODO 注册服务状态主题参与者 } XNFrameworkPtr XNServiceObject::GetFramework() const { T_D(); return d->pFramework; } void XNServiceObject::SetFramework(XNFrameworkPtr framework) { T_D(); d->pFramework = framework; } } // namespace XNSim