289 lines
10 KiB
C++
Executable File
289 lines
10 KiB
C++
Executable File
/**
|
||
* @file DataMonitorThread.cpp
|
||
* @author jinchao
|
||
* @brief 数据监控线程类实现
|
||
* @version 1.0
|
||
* @date 2025-03-10
|
||
*
|
||
* @copyright Copyright (c) 2025 COMAC
|
||
*
|
||
*/
|
||
#include "DataMonitorThread.h"
|
||
#include <QMutexLocker>
|
||
#include <QDebug>
|
||
#include <functional>
|
||
#include "../TopicManager/TopicManager.h"
|
||
#include "../TopicMonitorFactory/TopicMonitorFactory.h"
|
||
|
||
DataMonitorThread::DataMonitorThread(QObject *parent) : QThread(parent)
|
||
{
|
||
}
|
||
|
||
DataMonitorThread::~DataMonitorThread()
|
||
{
|
||
// 停止所有主题监控
|
||
if (m_TopicMonitorMap.size() > 0) {
|
||
for (auto &topicName : m_TopicMonitorMap.keys()) {
|
||
m_TopicMonitorMap[topicName]->stopMonitoring(topicName);
|
||
m_TopicMonitorMap.remove(topicName);
|
||
}
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::run()
|
||
{
|
||
while (!m_Quit) {
|
||
if (m_Active) {
|
||
QMutexLocker locker(&m_Mutex);
|
||
for (auto &topicName : m_VarNameMap.keys()) {
|
||
// 遍历主题名下的所有变量
|
||
for (auto &varName : m_VarNameMap[topicName].keys()) {
|
||
if (m_VarNameMap[topicName][varName] == 0) {
|
||
// 如果变量名对应的监控状态为0,则获取数据
|
||
QString value = m_TopicMonitorMap[topicName]->getData(topicName, varName);
|
||
emit updateMonitoringData(varName, value);
|
||
} else if (m_VarNameMap[topicName][varName] == 2) {
|
||
// 如果变量名对应的监控状态为2,则注入一次数据
|
||
m_TopicMonitorMap[topicName]->injectData(
|
||
varName, m_InjectValueMap[topicName][varName]);
|
||
emit updateMonitoringData(
|
||
varName, QString::number(m_InjectValueMap[topicName][varName]));
|
||
m_VarNameMap[topicName][varName] = 0;
|
||
m_InjectValueMap[topicName].remove(varName);
|
||
} else if (m_VarNameMap[topicName][varName] == 3) {
|
||
// 如果变量名对应的监控状态为3,则注入连续数据
|
||
m_TopicMonitorMap[topicName]->injectData(
|
||
varName, m_InjectValueMap[topicName][varName]);
|
||
emit updateMonitoringData(
|
||
varName, QString::number(m_InjectValueMap[topicName][varName]));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
QThread::msleep(m_SleepTime);
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::onSaveModelDefinition(
|
||
const QSharedPointer<ModelDefinition> &modelDefinition)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
|
||
// 首先检查输入参数是否为空
|
||
if (!modelDefinition) {
|
||
emit sendDebugMessage(1, "保存模型接口定义失败,ModelDefinition指针为空");
|
||
return;
|
||
}
|
||
|
||
// 设置最大递归深度
|
||
const int MAX_RECURSION_DEPTH = 5;
|
||
|
||
// 查找所有主题定义的结构体lambda表达式
|
||
std::function<void(const QString &, const QVector<QSharedPointer<NamespaceDefinition>> &, int)>
|
||
findAllStruct = [this, &findAllStruct, MAX_RECURSION_DEPTH](
|
||
const QString &topic,
|
||
const QVector<QSharedPointer<NamespaceDefinition>> &nsVector,
|
||
int depth) {
|
||
// 检查递归深度
|
||
if (depth > MAX_RECURSION_DEPTH) {
|
||
return;
|
||
}
|
||
|
||
for (auto &ns : nsVector) {
|
||
// 检查是否为空指针
|
||
if (!ns) {
|
||
continue;
|
||
}
|
||
// 计算新的主题名
|
||
QString newTopic =
|
||
topic.size() > 0 ? topic + "::" + ns->namespaceName : ns->namespaceName;
|
||
// 递归查找所有结构体
|
||
findAllStruct(newTopic, ns->childNamespaces, depth + 1);
|
||
|
||
for (auto &structDef : ns->structDefinitions) {
|
||
// 检查是否为空指针
|
||
if (!structDef) {
|
||
continue;
|
||
}
|
||
// 保存主题名和结构体定义
|
||
m_StructDefinitionList[newTopic + "::" + structDef->structName] = structDef;
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0,
|
||
"保存主题名" + newTopic + "::" + structDef->structName);
|
||
}
|
||
}
|
||
};
|
||
// 调用lambda表达式,查找所有主题定义的结构体
|
||
findAllStruct("", modelDefinition->namespaceDefinitions, 0);
|
||
}
|
||
|
||
void DataMonitorThread::onStartMonitoring(const QString &modelName, const QString &topicName,
|
||
const QString &varName)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
// 检查主题名是否在结构体列表中
|
||
if (m_StructDefinitionList.contains(topicName)) {
|
||
// 如果主题名在结构体列表中,则开始监控
|
||
if (StartTopicMonitor(modelName, topicName)) {
|
||
// 保存监控状态
|
||
m_VarNameMap[topicName][varName] = 0;
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0, "开始监控主题名" + topicName);
|
||
}
|
||
} else {
|
||
// 如果主题名不在结构体列表中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要监控的主题名" + topicName);
|
||
}
|
||
}
|
||
|
||
bool DataMonitorThread::StartTopicMonitor(const QString &modelName, const QString &topicName)
|
||
{
|
||
// 创建主题监控器
|
||
m_TopicMonitorMap[topicName] = TopicMonitorFactory::getInstance().createMonitor(modelName);
|
||
// 检查主题监控器是否创建成功
|
||
if (m_TopicMonitorMap[topicName]) {
|
||
// 开始监控
|
||
bool bRet = m_TopicMonitorMap[topicName]->startMonitoring(topicName);
|
||
// 返回监控结果
|
||
return bRet;
|
||
}
|
||
// 如果主题监控器创建失败,则返回false
|
||
return false;
|
||
}
|
||
|
||
void DataMonitorThread::onStopMonitoring(const QString &modelName, const QString &topicName,
|
||
const QString &varName)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
if (m_StructDefinitionList.contains(topicName)) {
|
||
// 如果变量名在监控状态中,则删除变量名对应的监控状态
|
||
if (m_VarNameMap[topicName].contains(varName))
|
||
m_VarNameMap[topicName].remove(varName);
|
||
// 如果主题名对应的监控状态表为空,则停止监控主题
|
||
if (m_VarNameMap[topicName].size() == 0) {
|
||
// 如果主题监控器不存在,则获取主题监控器
|
||
if (!m_TopicMonitorMap[topicName]) {
|
||
m_TopicMonitorMap[topicName] =
|
||
TopicMonitorFactory::getInstance().createMonitor(modelName);
|
||
}
|
||
// 停止监控主题
|
||
m_TopicMonitorMap[topicName]->stopMonitoring(topicName);
|
||
// 删除主题监控器
|
||
m_TopicMonitorMap.remove(topicName);
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0, "停止监控主题名" + topicName);
|
||
}
|
||
} else {
|
||
// 如果主题名不在结构体列表中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要停止监控的主题名" + topicName);
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::onPauseMonitoring(const QString &modelName, const QString &topicName,
|
||
const QString &varName)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
if (m_VarNameMap.contains(topicName)) {
|
||
// 如果变量名在监控状态中,则暂停监控
|
||
if (m_VarNameMap[topicName].contains(varName)) {
|
||
m_VarNameMap[topicName][varName] = 1;
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0, "暂停监控主题名" + topicName + "的变量" + varName);
|
||
} else {
|
||
// 如果变量名不在监控状态中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要暂停监控的主题名" + topicName + "的变量" + varName);
|
||
}
|
||
} else {
|
||
// 如果主题名不在监控状态中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要暂停监控的主题名" + topicName);
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::onResumeMonitoring(const QString &modelName, const QString &topicName,
|
||
const QString &varName)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
if (m_VarNameMap.contains(topicName)) {
|
||
// 如果变量名在监控状态中,则恢复监控
|
||
if (m_VarNameMap[topicName].contains(varName)) {
|
||
m_VarNameMap[topicName][varName] = 0;
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0, "恢复监控主题名" + topicName + "的变量" + varName);
|
||
} else {
|
||
// 如果变量名不在监控状态中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要恢复监控的主题名" + topicName + "的变量" + varName);
|
||
}
|
||
} else {
|
||
// 如果主题名不在监控状态中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要恢复监控的主题名" + topicName);
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::onInjectOnceData(const QString &modelName, const QString &topicName,
|
||
const QString &varName, const double &value)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
// 检查主题名是否在结构体列表中
|
||
if (m_StructDefinitionList.contains(topicName)) {
|
||
// 保存监控状态
|
||
m_VarNameMap[topicName][varName] = 2;
|
||
// 保存注入值
|
||
m_InjectValueMap[topicName][varName] = value;
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0, "注入一次数据主题名" + topicName + "的变量" + varName);
|
||
} else {
|
||
// 如果主题名不在结构体列表中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要注入一次数据的主题名" + topicName);
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::onInjectContinuousData(const QString &modelName, const QString &topicName,
|
||
const QString &varName, const double &value)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
if (m_StructDefinitionList.contains(topicName)) {
|
||
// 保存监控状态
|
||
m_VarNameMap[topicName][varName] = 3;
|
||
// 保存注入值
|
||
m_InjectValueMap[topicName][varName] = value;
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0, "注入连续数据主题名" + topicName + "的变量" + varName);
|
||
} else {
|
||
// 如果主题名不在结构体列表中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要注入连续数据的主题名" + topicName);
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::onStopInjectContinuousData(const QString &modelName,
|
||
const QString &topicName, const QString &varName)
|
||
{
|
||
QMutexLocker locker(&m_Mutex);
|
||
if (m_VarNameMap.contains(topicName)) {
|
||
// 如果变量名在监控状态中,则停止注入连续数据
|
||
if (m_VarNameMap[topicName].contains(varName)) {
|
||
m_VarNameMap[topicName][varName] = 0;
|
||
// 删除注入值
|
||
m_InjectValueMap[topicName].remove(varName);
|
||
// 发送调试信息
|
||
emit sendDebugMessage(0, "停止注入连续数据主题名" + topicName + "的变量" + varName);
|
||
} else {
|
||
// 如果变量名不在监控状态中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要停止注入连续数据的主题名" + topicName + "的变量"
|
||
+ varName);
|
||
}
|
||
} else {
|
||
// 如果主题名不在监控状态中,则发送调试信息
|
||
emit sendDebugMessage(2, "未找到需要停止注入连续数据的主题名" + topicName);
|
||
}
|
||
}
|
||
|
||
void DataMonitorThread::onChangeSleepTime(const unsigned int newSleepTime)
|
||
{
|
||
m_SleepTime = newSleepTime;
|
||
}
|
||
|
||
void DataMonitorThread::onThreadController(const bool &isActive)
|
||
{
|
||
m_Active = isActive;
|
||
}
|