295 lines
8.2 KiB
C++
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
|