XNSim/XNCore_Win/XNServiceObject/XNServiceObject.cpp

295 lines
8.2 KiB
C++

#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<std::string>());
// TODO: 处理服务命令信息
// d->_commandList.emplace_back(
// cmd["Name"].get<std::string>(),
// cmd["Description"].get<std::string>(),
// cmd["Call"].get<std::string>()
// );
}
}
}
} 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