GrabBag/AppUtils/AppCommon/Src/ConfigMonitor.cpp

246 lines
7.9 KiB
C++

#include "ConfigMonitor.h"
#include "VrLog.h"
#include "VrError.h"
#include <cstring>
#include <chrono>
ConfigMonitor::ConfigMonitor()
: m_pShareMem(nullptr)
, m_pCommandHandler(nullptr)
, m_bMonitorRunning(false)
{
}
ConfigMonitor::~ConfigMonitor()
{
Stop();
}
void ConfigMonitor::SetCommandHandler(IConfigCommandHandler* handler)
{
m_pCommandHandler = handler;
}
bool ConfigMonitor::Start(const std::string& sharedMemName)
{
if (m_bMonitorRunning) {
LOG_WARNING("[ConfigMonitor] Monitor is already running\n");
return true;
}
if (!m_pCommandHandler) {
LOG_ERROR("[ConfigMonitor] Command handler not set\n");
return false;
}
m_sharedMemName = sharedMemName;
if (!InitializeSharedMemory(sharedMemName)) {
LOG_ERROR("[ConfigMonitor] Failed to initialize shared memory\n");
return false;
}
// 启动监控线程
m_bMonitorRunning = true;
m_monitorThread = std::thread(&ConfigMonitor::MonitorThreadFunc, this);
LOG_INFO("[ConfigMonitor] Shared memory monitor started (name: %s)\n", sharedMemName.c_str());
return true;
}
void ConfigMonitor::Stop()
{
if (!m_bMonitorRunning) {
return;
}
LOG_INFO("[ConfigMonitor] Stopping shared memory monitor...\n");
m_bMonitorRunning = false;
// 等待线程结束
if (m_monitorThread.joinable()) {
m_monitorThread.join();
}
// 清理共享内存
CleanupSharedMemory();
LOG_INFO("[ConfigMonitor] Shared memory monitor stopped\n");
}
void ConfigMonitor::MonitorThreadFunc()
{
LOG_INFO("[ConfigMonitor] Monitor thread started\n");
ConfigCmdSharedData lastData;
memset(&lastData, 0, sizeof(ConfigCmdSharedData));
while (m_bMonitorRunning) {
try {
// 锁定共享内存并读取数据
int ret = m_pShareMem->Lock(1000); // 1秒超时
if (ret != SUCCESS) {
if (ret != SHAREMEM_ERR_TIMEOUT) {
LOG_ERROR("[ConfigMonitor] Failed to lock shared memory, error: %d\n", ret);
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
ConfigCmdSharedData currentData;
ret = m_pShareMem->ReadData(0, &currentData, sizeof(ConfigCmdSharedData));
m_pShareMem->Unlock();
if (ret < 0) {
LOG_ERROR("[ConfigMonitor] Failed to read shared memory, error: %d\n", ret);
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 检查魔数和版本
if (strcmp(currentData.header.magic, "VRCFG001") != 0 || currentData.header.version != 1) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 检查是否有新数据
if (!currentData.header.hasNewData) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 验证校验和
if (!currentData.ValidateChecksum()) {
LOG_ERROR("[ConfigMonitor] Config command data checksum validation failed\n");
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 检查是否是新的命令(与上次不同)
if (memcmp(&lastData.data, &currentData.data, sizeof(ConfigCmdData)) == 0) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
continue;
}
// 应用配置命令
LOG_INFO("[ConfigMonitor] Received new config command, type: %d, timestamp: %s\n",
currentData.data.cmdType, currentData.data.timestamp);
if (ApplyConfigCommand(currentData.data)) {
LOG_INFO("[ConfigMonitor] Config command applied successfully\n");
} else {
LOG_ERROR("[ConfigMonitor] Failed to apply config command\n");
}
// 更新最后处理的数据
lastData = currentData;
// 标记数据已处理(清除新数据标志)
ret = m_pShareMem->Lock(1000);
if (ret == SUCCESS) {
ConfigCmdSharedData clearData = currentData;
clearData.header.hasNewData = false;
m_pShareMem->WriteData(0, &clearData, sizeof(ConfigCmdSharedData));
m_pShareMem->Unlock();
}
} catch (const std::exception& e) {
LOG_ERROR("[ConfigMonitor] Exception in monitor thread: %s\n", e.what());
}
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
LOG_INFO("[ConfigMonitor] Monitor thread stopped\n");
}
bool ConfigMonitor::InitializeSharedMemory(const std::string& sharedMemName)
{
if (m_pShareMem) {
return true; // 已经初始化
}
m_pShareMem = CreateShareMemInstance();
if (!m_pShareMem) {
LOG_ERROR("[ConfigMonitor] Failed to create shared memory instance\n");
return false;
}
// 尝试打开已存在的共享内存,如果不存在则创建
int ret = m_pShareMem->CreateOrOpen(sharedMemName, CONFIG_CMD_SHARED_MEM_SIZE, false);
if (ret != SUCCESS) {
// 如果打开失败,尝试创建新的
ret = m_pShareMem->CreateOrOpen(sharedMemName, CONFIG_CMD_SHARED_MEM_SIZE, true);
if (ret != SUCCESS) {
LOG_ERROR("[ConfigMonitor] Failed to create or open shared memory, error: %d\n", ret);
CleanupSharedMemory();
return false;
}
}
// 映射内存
void* mappedAddr = m_pShareMem->MapView();
if (!mappedAddr) {
LOG_ERROR("[ConfigMonitor] Failed to map shared memory view\n");
CleanupSharedMemory();
return false;
}
LOG_INFO("[ConfigMonitor] Shared memory initialized successfully (name: %s, size: %zu)\n",
sharedMemName.c_str(), CONFIG_CMD_SHARED_MEM_SIZE);
return true;
}
void ConfigMonitor::CleanupSharedMemory()
{
if (m_pShareMem) {
m_pShareMem->UnmapView();
m_pShareMem->Close();
DestroyShareMemInstance(m_pShareMem);
m_pShareMem = nullptr;
}
}
bool ConfigMonitor::ApplyConfigCommand(const ConfigCmdData& configData)
{
if (!m_pCommandHandler) {
LOG_ERROR("[ConfigMonitor] Command handler not set\n");
return false;
}
switch (configData.cmdType) {
case CONFIG_CMD_CAMERA_EXPOSE:
return m_pCommandHandler->OnCameraExposeCommand(configData.cameraParam);
case CONFIG_CMD_CAMERA_GAIN:
return m_pCommandHandler->OnCameraGainCommand(configData.cameraParam);
case CONFIG_CMD_CAMERA_FRAMERATE:
return m_pCommandHandler->OnCameraFrameRateCommand(configData.cameraParam);
case CONFIG_CMD_CAMERA_SWING:
return m_pCommandHandler->OnCameraSwingCommand(configData.swingParam);
case CONFIG_CMD_ALGO_PARAM:
return m_pCommandHandler->OnAlgoParamCommand(configData.algoParam);
case CONFIG_CMD_CALIB_PARAM:
return m_pCommandHandler->OnCalibParamCommand(configData.calibParam);
case CONFIG_CMD_FULL_CONFIG:
return m_pCommandHandler->OnFullConfigCommand(configData.fullConfigParam);
case CONFIG_CMD_SWITCH_WORKPOSITION:
return m_pCommandHandler->OnSwitchWorkPositionCommand(configData.switchWorkPositionParam);
case CONFIG_CMD_SWITCH_PACKAGETYPE:
return m_pCommandHandler->OnSwitchPackageTypeCommand(configData.switchPackageTypeParam);
default:
LOG_ERROR("[ConfigMonitor] Unknown config command type: %d\n", configData.cmdType);
return false;
}
}