XNSim/XNMonitor/DataMonitorWidget/DataMonitorThread.cpp

289 lines
10 KiB
C++
Raw Permalink Normal View History

2025-04-28 12:25:20 +08:00
/**
* @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;
}