#include "XNServiceObject.h" #include "XNServiceObject_p.h" #include "XNEventManager.h" #include "XNFramework.h" XNServiceObject::XNServiceObject() : XNObject(new XNServiceObjectPrivate()) { T_D(); d->_initialType = 0; } XNServiceObject::~XNServiceObject() { } XNServiceObject::XNServiceObject(PrivateType *p) : XNObject(p) { } const std::string &XNServiceObject::GetVersion() { T_D(); return d->_sVersion; } const std::string &XNServiceObject::GetDescription() { T_D(); return d->_sDescription; } const std::string &XNServiceObject::GetAuthor() { T_D(); return d->_sAuthor; } const std::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 std::string &version) { T_D(); d->_sVersion = version; } void XNServiceObject::SetDescription(const std::string &sDescription) { T_D(); d->_sDescription = sDescription; } void XNServiceObject::SetAuthor(const std::string &sAuthor) { T_D(); d->_sAuthor = sAuthor; } void XNServiceObject::SetXmlPath(const std::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; } int XNServiceObject::RegisterEventHandler(const std::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 std::string &eventName, const std::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); } } } int XNServiceObject::RegisterRTEventHandler(const std::string &eventName, XNEventCallback callback) { return RegisterEventHandler(eventName, callback, true, XNEvent::Priority::RealTime); } void XNServiceObject::TriggerRTEvent(const std::string &eventName, const std::any &eventData) { TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime); } void XNServiceObject::SetInitializeType(uint32_t initialType) { T_D(); d->_initialType = initialType; } void XNServiceObject::Initialize() { T_D(); if (d->_initialType == 0) { ParseXml(); } else { ParseConfig(); } } void XNServiceObject::ParseXml() { T_D(); tinyxml2::XMLDocument doc; if (doc.LoadFile(GetXmlPath().c_str()) != tinyxml2::XML_SUCCESS) { LOG_WARNING("Failed to open the service configuration file: %1!", GetXmlPath()); return; } tinyxml2::XMLElement *rootNode = doc.RootElement(); if (!rootNode) { LOG_WARNING("Invalid XML file format: %1!", GetXmlPath()); return; } const char *serviceName = rootNode->FirstChildElement("Name")->GetText(); 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 = rootNode->FirstChildElement("Description")->GetText(); d->_sAuthor = rootNode->FirstChildElement("Author")->GetText(); d->_sVersion = rootNode->FirstChildElement("Version")->GetText(); // 解析时间 const char *createTimeStr = rootNode->FirstChildElement("CreateTime")->GetText(); const char *changeTimeStr = rootNode->FirstChildElement("ChangeTime")->GetText(); d->_cCreateTime = XNSim::parseISOTime(createTimeStr); d->_cChangeTime = XNSim::parseISOTime(changeTimeStr); tinyxml2::XMLElement *nodeCmds = rootNode->FirstChildElement("CommandList"); if (nodeCmds) { for (tinyxml2::XMLElement *nodeCmd = nodeCmds->FirstChildElement("Command"); nodeCmd != nullptr; nodeCmd = nodeCmd->NextSiblingElement("Command")) { const char *cmdName = nodeCmd->Attribute("Name"); const char *cmdDescription = nodeCmd->Attribute("Description"); const char *cmdCall = nodeCmd->Attribute("Call"); // TODO: 处理命令信息 } } } void XNServiceObject::ParseConfig() { T_D(); std::vector nameAndVersion = XNSim::split(GetXmlPath(), ","); std::string serviceName = nameAndVersion[0]; std::string serviceVersion = nameAndVersion[1]; // 获取数据库路径 std::string dbPath = std::getenv("XNCore"); if (dbPath.empty()) { LOG_ERROR("0x1015 未设置XNCore环境变量, 引擎将退出!"); return; } dbPath += "/database/XNSim.db"; // 打开数据库 sqlite3 *db; if (sqlite3_open(dbPath.c_str(), &db) != SQLITE_OK) { LOG_ERROR("0x1016 打开数据库失败: %1", sqlite3_errmsg(db)); return; } // 准备SQL语句 std::string sql = "SELECT * FROM XNServiceVersion WHERE ClassName = ? AND Version = ?"; sqlite3_stmt *stmt; if (sqlite3_prepare_v2(db, sql.c_str(), -1, &stmt, nullptr) != SQLITE_OK) { LOG_ERROR("0x1017 准备SQL语句失败: %1", sqlite3_errmsg(db)); sqlite3_close(db); return; } // 绑定参数 if (sqlite3_bind_text(stmt, 1, serviceName.c_str(), serviceName.length(), nullptr) != SQLITE_OK || sqlite3_bind_text(stmt, 2, serviceVersion.c_str(), serviceVersion.length(), nullptr) != SQLITE_OK) { LOG_ERROR("0x1018 绑定参数失败: %1", sqlite3_errmsg(db)); sqlite3_finalize(stmt); sqlite3_close(db); return; } // 执行查询 if (sqlite3_step(stmt) != SQLITE_ROW) { LOG_ERROR("0x1019 未找到服务名称为%1,版本号%2的记录", serviceName.c_str(), serviceVersion.c_str()); sqlite3_finalize(stmt); sqlite3_close(db); return; } d->_sDescription = XNSim::getStringFromSqlite3(stmt, 5); d->_sAuthor = XNSim::getStringFromSqlite3(stmt, 4); d->_sVersion = XNSim::getStringFromSqlite3(stmt, 2); // 解析时间 std::string createTimeStr = XNSim::getStringFromSqlite3(stmt, 6); std::string changeTimeStr = XNSim::getStringFromSqlite3(stmt, 7); d->_cCreateTime = XNSim::parseISOTime(createTimeStr); d->_cChangeTime = XNSim::parseISOTime(changeTimeStr); // 读取服务命令列表 std::string commandListStr = XNSim::getStringFromSqlite3(stmt, 8); if (!commandListStr.empty()) { try { XN_JSON commandList = XN_JSON::parse(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()); } } // 读取其他参数 std::string otherParamsStr = XNSim::getStringFromSqlite3(stmt, 9); if (!otherParamsStr.empty()) { try { d->_otherParams = XN_JSON::parse(otherParamsStr); } catch (const std::exception &e) { LOG_WARNING("0x1020 解析其他参数失败: %1", e.what()); } } // 清理资源 sqlite3_finalize(stmt); sqlite3_close(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; }