XNSim/XNCore/XNServiceObject.cpp

313 lines
7.9 KiB
C++
Raw Permalink Normal View History

2025-04-28 12:25:20 +08:00
#include "XNServiceObject.h"
#include "XNServiceObject_p.h"
2025-05-20 15:39:40 +08:00
#include "XNEventManager.h"
#include "XNFramework.h"
2025-04-28 12:25:20 +08:00
2025-05-20 15:39:40 +08:00
XNServiceObject::XNServiceObject() : XNObject(new XNServiceObjectPrivate())
2025-04-28 12:25:20 +08:00
{
2025-05-22 16:22:48 +08:00
T_D();
d->_initialType = 0;
2025-04-28 12:25:20 +08:00
}
XNServiceObject::~XNServiceObject()
{
}
2025-05-20 15:39:40 +08:00
XNServiceObject::XNServiceObject(PrivateType *p) : XNObject(p)
2025-04-28 12:25:20 +08:00
{
}
2025-05-20 15:39:40 +08:00
const std::string &XNServiceObject::GetVersion()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
return d->_sVersion;
}
2025-05-20 15:39:40 +08:00
const std::string &XNServiceObject::GetDescription()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
return d->_sDescription;
}
2025-05-20 15:39:40 +08:00
const std::string &XNServiceObject::GetAuthor()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
return d->_sAuthor;
}
2025-05-20 15:39:40 +08:00
const std::string &XNServiceObject::GetXmlPath()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
return d->_sXmlPath;
}
2025-05-20 15:39:40 +08:00
const XNTimePoint &XNServiceObject::GetCreateTime()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
return d->_cCreateTime;
}
2025-05-20 15:39:40 +08:00
const XNTimePoint &XNServiceObject::GetChangeTime()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
return d->_cChangeTime;
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::SetVersion(const std::string &version)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
d->_sVersion = version;
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::SetDescription(const std::string &sDescription)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
d->_sDescription = sDescription;
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::SetAuthor(const std::string &sAuthor)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
d->_sAuthor = sAuthor;
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::SetXmlPath(const std::string &sXmlPath)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
d->_sXmlPath = sXmlPath;
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::SetCreateTime(const XNTimePoint &cTime)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
d->_cCreateTime = cTime;
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::SetChangeTime(const XNTimePoint &cTime)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
d->_cChangeTime = cTime;
}
2025-05-20 15:39:40 +08:00
int XNServiceObject::RegisterEventHandler(const std::string &eventName, XNEventCallback callback,
2025-04-28 12:25:20 +08:00
bool async, XNEvent::Priority priority)
{
// 注册事件处理器
2025-05-20 15:39:40 +08:00
T_D();
auto framework = GetFramework();
if (framework) {
auto eventManager = framework->GetEventManager();
if (eventManager) {
return eventManager->RegisterEventHandler(eventName, callback, GetUniqueId(), async,
2025-04-28 12:25:20 +08:00
priority);
2025-05-20 15:39:40 +08:00
}
2025-04-28 12:25:20 +08:00
}
return -1;
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::TriggerEvent(const std::string &eventName, const std::any &eventData,
2025-04-28 12:25:20 +08:00
bool forceAsync, XNEvent::Priority priority)
{
// 触发事件
2025-05-20 15:39:40 +08:00
T_D();
auto framework = GetFramework();
if (framework) {
auto eventManager = framework->GetEventManager();
if (eventManager) {
eventManager->TriggerEvent(eventName, eventData, forceAsync, priority);
}
2025-04-28 12:25:20 +08:00
}
}
2025-05-20 15:39:40 +08:00
int XNServiceObject::RegisterRTEventHandler(const std::string &eventName, XNEventCallback callback)
2025-04-28 12:25:20 +08:00
{
return RegisterEventHandler(eventName, callback, true, XNEvent::Priority::RealTime);
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::TriggerRTEvent(const std::string &eventName, const std::any &eventData)
2025-04-28 12:25:20 +08:00
{
TriggerEvent(eventName, eventData, true, XNEvent::Priority::RealTime);
}
2025-05-22 16:22:48 +08:00
void XNServiceObject::SetInitializeType(uint32_t initialType)
{
T_D();
d->_initialType = initialType;
}
void XNServiceObject::Initialize()
2025-05-20 15:39:40 +08:00
{
T_D();
2025-05-22 16:22:48 +08:00
if (d->_initialType == 0) {
ParseXml();
} else {
ParseConfig();
}
}
2025-05-20 15:39:40 +08:00
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;
}
2025-05-20 15:39:40 +08:00
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: 处理命令信息
2025-05-20 15:39:40 +08:00
}
}
}
void XNServiceObject::ParseConfig()
{
T_D();
std::vector<std::string> 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;
}
2025-05-20 15:39:40 +08:00
// 执行查询
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<std::string>());
// TODO: 处理服务命令信息
// d->_commandList.emplace_back(
// cmd["Name"].get<std::string>(),
// cmd["Description"].get<std::string>(),
// cmd["Call"].get<std::string>()
// );
}
}
2025-05-20 15:39:40 +08:00
}
} catch (const std::exception &e) {
LOG_WARNING("0x1020 解析服务命令列表失败: %1", e.what());
2025-05-20 15:39:40 +08:00
}
2025-04-28 12:25:20 +08:00
}
// 读取其他参数
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);
2025-04-28 12:25:20 +08:00
}
2025-05-20 15:39:40 +08:00
void XNServiceObject::PrepareForExecute()
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
RegisterDDSParticipant();
}
void XNServiceObject::RegisterDDSParticipant()
{
2025-05-20 15:39:40 +08:00
T_D();
2025-04-28 12:25:20 +08:00
//TODO 注册服务状态主题参与者
}
2025-05-20 15:39:40 +08:00
XNFrameworkPtr XNServiceObject::GetFramework() const
{
T_D();
return d->pFramework;
}
void XNServiceObject::SetFramework(XNFrameworkPtr framework)
2025-04-28 12:25:20 +08:00
{
2025-05-20 15:39:40 +08:00
T_D();
d->pFramework = framework;
2025-04-28 12:25:20 +08:00
}