GrabBag/AppUtils/AppCommon/Inc/BaseConfigManager.h

571 lines
18 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef BASECONFIGMANAGER_H
#define BASECONFIGMANAGER_H
#include "ConfigMonitor.h"
#include <mutex>
#include <vector>
#include <functional>
#include <memory>
#include <string>
#include <algorithm>
#include <cstring>
#include <QtCore/QCoreApplication>
#include "VrLog.h"
// 前置声明,具体定义由各应用的 IVrConfig.h 提供
class IVrConfig;
struct ConfigResult;
struct VrAlgorithmParams;
struct DeviceInfo;
/**
* @brief 扩展的相机UI参数
*/
struct CameraUIParam
{
int cameraIndex = 1; // 相机索引
double exposeTime = 100.0; // 曝光时间 (微秒)
double gain = 1.0; // 增益值
double frameRate = 30.0; // 帧率
double swingSpeed = 10.0; // 摆动速度
double swingStartAngle = 0.0; // 开始角度
double swingStopAngle = 180.0; // 结束角度
};
/**
* @brief 完整的系统配置数据
*/
struct SystemConfig
{
ConfigResult configResult; // VrConfig配置结果
std::vector<CameraUIParam> cameraUIParams; // 相机UI参数
// 获取指定相机的UI参数
CameraUIParam* GetCameraUIParam(int cameraIndex)
{
for (auto& param : cameraUIParams) {
if (param.cameraIndex == cameraIndex) {
return &param;
}
}
return nullptr;
}
const CameraUIParam* GetCameraUIParam(int cameraIndex) const
{
for (const auto& param : cameraUIParams) {
if (param.cameraIndex == cameraIndex) {
return &param;
}
}
return nullptr;
}
// 设置或更新指定相机的UI参数
void SetCameraUIParam(const CameraUIParam& param)
{
for (auto& existingParam : cameraUIParams) {
if (existingParam.cameraIndex == param.cameraIndex) {
existingParam = param;
return;
}
}
// 如果不存在,则添加新的
cameraUIParams.push_back(param);
}
// 确保指定相机的参数存在
void EnsureCameraUIParam(int cameraIndex)
{
for (const auto& param : cameraUIParams) {
if (param.cameraIndex == cameraIndex) {
return; // 已存在
}
}
// 不存在,创建默认参数
CameraUIParam defaultParam;
defaultParam.cameraIndex = cameraIndex;
cameraUIParams.push_back(defaultParam);
}
};
/**
* @brief 配置变化监听器接口
*/
class IConfigChangeListener
{
public:
virtual ~IConfigChangeListener() = default;
/**
* @brief 配置变化通知
* @param config 新的配置数据
*/
virtual void OnSystemConfigChanged(const SystemConfig& config) = 0;
/**
* @brief 相机参数变化通知
* @param cameraIndex 相机索引
* @param cameraParam 相机参数
*/
virtual void OnCameraParamChanged(int cameraIndex, const CameraUIParam& cameraParam) = 0;
/**
* @brief 算法参数变化通知
* @param algorithmParams 算法参数
*/
virtual void OnAlgorithmParamChanged(const VrAlgorithmParams& algorithmParams) = 0;
};
/**
* @brief 配置管理器基类
*
* Header-only 实现,避免编译依赖问题
* 提供通用的配置管理功能
*/
class BaseConfigManager : public IConfigCommandHandler
{
public:
BaseConfigManager()
: m_pVrConfig(nullptr)
{
}
virtual ~BaseConfigManager()
{
Shutdown();
}
// 基本配置管理
virtual bool Initialize(const std::string& configFilePath = "")
{
LOG_INFO("BaseConfigManager initializing...\n");
// 保存配置文件路径
if (configFilePath.empty()) {
QString defaultPath = QCoreApplication::applicationDirPath() + "/config.json";
m_configFilePath = defaultPath.toStdString();
} else {
m_configFilePath = configFilePath;
}
// 创建VrConfig实例
if (!IVrConfig::CreateInstance(&m_pVrConfig) || !m_pVrConfig) {
LOG_ERROR("Failed to create VrConfig instance\n");
return false;
}
// 加载配置文件
if (!LoadConfigFromFile(m_configFilePath)) {
LOG_WARNING("Failed to load config file, using default config\n");
_InitializeDefaultConfig();
}
// 启动 ConfigMonitor
m_configMonitor.SetCommandHandler(this);
if (!m_configMonitor.Start()) {
LOG_WARNING("Failed to start ConfigMonitor, config updates from shared memory will not work\n");
}
LOG_INFO("BaseConfigManager initialized successfully\n");
return true;
}
virtual void Shutdown()
{
LOG_INFO("BaseConfigManager shutting down...\n");
// 停止 ConfigMonitor
m_configMonitor.Stop();
// 清理监听器
{
std::lock_guard<std::mutex> lock(m_listenersMutex);
m_listeners.clear();
}
// 释放VrConfig实例
if (m_pVrConfig) {
delete m_pVrConfig;
m_pVrConfig = nullptr;
}
LOG_INFO("BaseConfigManager shutdown completed\n");
}
// 配置访问(线程安全)
SystemConfig GetConfig() const
{
std::lock_guard<std::mutex> lock(m_configMutex);
return m_systemConfig;
}
CameraUIParam GetCameraUIParam(int cameraIndex) const
{
std::lock_guard<std::mutex> lock(m_configMutex);
const CameraUIParam* param = m_systemConfig.GetCameraUIParam(cameraIndex);
if (param) {
return *param;
}
// 返回默认参数
CameraUIParam defaultParam;
defaultParam.cameraIndex = cameraIndex;
return defaultParam;
}
VrAlgorithmParams GetAlgorithmParams() const
{
std::lock_guard<std::mutex> lock(m_configMutex);
return m_systemConfig.configResult.algorithmParams;
}
ConfigResult GetConfigResult() const
{
std::lock_guard<std::mutex> lock(m_configMutex);
return m_systemConfig.configResult;
}
IVrConfig* GetVrConfigInstance() const { return m_pVrConfig; }
// 配置更新
bool UpdateCameraUIParam(int cameraIndex, const CameraUIParam& param)
{
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
CameraUIParam* existingParam = m_systemConfig.GetCameraUIParam(cameraIndex);
if (!existingParam || memcmp(existingParam, &param, sizeof(CameraUIParam)) != 0) {
m_systemConfig.SetCameraUIParam(param);
changed = true;
}
}
if (changed) {
_NotifyCameraParamChanged(cameraIndex);
LOG_INFO("Camera %d UI parameters updated\n", cameraIndex);
}
return true;
}
bool UpdateAlgorithmParams(const VrAlgorithmParams& params)
{
bool changed = false;
{
std::lock_guard<std::mutex> lock(m_configMutex);
if (memcmp(&m_systemConfig.configResult.algorithmParams, &params, sizeof(VrAlgorithmParams)) != 0) {
m_systemConfig.configResult.algorithmParams = params;
changed = true;
}
}
if (changed) {
_NotifyAlgorithmParamChanged();
LOG_INFO("Algorithm parameters updated\n");
}
return true;
}
bool UpdateFullConfig(const SystemConfig& config)
{
{
std::lock_guard<std::mutex> lock(m_configMutex);
m_systemConfig = config;
}
_NotifyConfigChanged();
LOG_INFO("Full configuration updated\n");
return true;
}
// 配置文件操作(纯虚函数,子类必须实现以适配不同的 IVrConfig API
virtual bool LoadConfigFromFile(const std::string& filePath) = 0;
bool SaveConfigToFile(const std::string& filePath)
{
if (!m_pVrConfig) {
LOG_ERROR("VrConfig instance not available\n");
return false;
}
try {
ConfigResult configResult;
{
std::lock_guard<std::mutex> lock(m_configMutex);
configResult = m_systemConfig.configResult;
}
bool result = m_pVrConfig->SaveConfig(filePath, configResult);
if (result) {
LOG_INFO("Configuration saved to file: %s\n", filePath.c_str());
} else {
LOG_ERROR("Failed to save configuration to file: %s\n", filePath.c_str());
}
return result;
} catch (const std::exception& e) {
LOG_ERROR("Exception while saving configuration to file %s: %s\n", filePath.c_str(), e.what());
return false;
}
}
// 监听器管理
void AddConfigChangeListener(std::shared_ptr<IConfigChangeListener> listener)
{
std::lock_guard<std::mutex> lock(m_listenersMutex);
m_listeners.push_back(listener);
LOG_DEBUG("Config change listener added, total listeners: %zu\n", m_listeners.size());
}
void RemoveConfigChangeListener(std::shared_ptr<IConfigChangeListener> listener)
{
std::lock_guard<std::mutex> lock(m_listenersMutex);
auto it = std::find_if(m_listeners.begin(), m_listeners.end(),
[&listener](const std::weak_ptr<IConfigChangeListener>& weak_listener) {
return weak_listener.lock() == listener;
});
if (it != m_listeners.end()) {
m_listeners.erase(it);
LOG_DEBUG("Config change listener removed, remaining listeners: %zu\n", m_listeners.size());
}
}
// IConfigCommandHandler 接口实现
bool OnCameraExposeCommand(const CameraConfigParam& param) override
{
LOG_INFO("Received camera expose command: camera=%d, exposeTime=%f\n", param.cameraIndex, param.exposeTime);
CameraUIParam cameraParam = GetCameraUIParam(param.cameraIndex);
cameraParam.exposeTime = param.exposeTime;
return UpdateCameraUIParam(param.cameraIndex, cameraParam);
}
bool OnCameraGainCommand(const CameraConfigParam& param) override
{
LOG_INFO("Received camera gain command: camera=%d, gain=%f\n", param.cameraIndex, param.gain);
CameraUIParam cameraParam = GetCameraUIParam(param.cameraIndex);
cameraParam.gain = param.gain;
return UpdateCameraUIParam(param.cameraIndex, cameraParam);
}
bool OnCameraFrameRateCommand(const CameraConfigParam& param) override
{
LOG_INFO("Received camera framerate command: camera=%d, frameRate=%f\n", param.cameraIndex, param.frameRate);
CameraUIParam cameraParam = GetCameraUIParam(param.cameraIndex);
cameraParam.frameRate = param.frameRate;
return UpdateCameraUIParam(param.cameraIndex, cameraParam);
}
bool OnCameraSwingCommand(const SwingConfigParam& param) override
{
LOG_INFO("Received camera swing command: camera=%d, swingSpeed=%f, start=%f, stop=%f\n",
param.cameraIndex, param.swingSpeed, param.startAngle, param.stopAngle);
CameraUIParam cameraParam = GetCameraUIParam(param.cameraIndex);
cameraParam.swingSpeed = param.swingSpeed;
cameraParam.swingStartAngle = param.startAngle;
cameraParam.swingStopAngle = param.stopAngle;
return UpdateCameraUIParam(param.cameraIndex, cameraParam);
}
bool OnAlgoParamCommand(const AlgoConfigParam& param) override
{
LOG_INFO("Received algorithm param command: %s=%f\n", param.paramName, param.paramValue);
VrAlgorithmParams algoParams = GetAlgorithmParams();
// 根据 param 中的数据更新算法参数
// 这里需要根据实际的 AlgoConfigParam 结构来映射
// 暂时简单处理
return UpdateAlgorithmParams(algoParams);
}
bool OnFullConfigCommand(const FullConfigParam& param) override
{
LOG_INFO("Received full config command\n");
// 重新加载配置文件
if (!m_configFilePath.empty()) {
return LoadConfigFromFile(m_configFilePath);
}
LOG_WARNING("Config file path not set, cannot reload full config\n");
return false;
}
// 应用特定的命令处理(默认实现)
bool OnCalibParamCommand(const CalibConfigParam& param) override
{
LOG_INFO("Received calibration param command: camera=%d\n", param.cameraIndex);
LOG_INFO("Calibration command received but not implemented in base class\n");
return true;
}
bool OnSwitchWorkPositionCommand(const SwitchWorkPositionParam& param) override
{
LOG_INFO("Received switch work position command: workPositionId=%s\n", param.workPositionId);
LOG_INFO("Switch work position command received but not implemented in base class\n");
return true;
}
bool OnSwitchPackageTypeCommand(const SwitchPackageTypeParam& param) override
{
LOG_INFO("Received switch package type command: packageTypeId=%s\n", param.packageTypeId);
LOG_INFO("Switch package type command received but not implemented in base class\n");
return true;
}
protected:
// 配置数据
mutable std::mutex m_configMutex;
SystemConfig m_systemConfig;
std::string m_configFilePath;
// VrConfig实例
IVrConfig* m_pVrConfig;
// 监听器管理
mutable std::mutex m_listenersMutex;
std::vector<std::weak_ptr<IConfigChangeListener>> m_listeners;
// ConfigMonitor 实例
ConfigMonitor m_configMonitor;
// 通知相关
void _NotifyConfigChanged()
{
SystemConfig currentConfig = GetConfig();
std::lock_guard<std::mutex> lock(m_listenersMutex);
_CleanupExpiredListeners();
for (auto& weakListener : m_listeners) {
if (auto listener = weakListener.lock()) {
try {
listener->OnSystemConfigChanged(currentConfig);
} catch (const std::exception& e) {
LOG_ERROR("Exception in config change listener: %s\n", e.what());
}
}
}
}
void _NotifyCameraParamChanged(int cameraIndex)
{
CameraUIParam cameraParam = GetCameraUIParam(cameraIndex);
std::lock_guard<std::mutex> lock(m_listenersMutex);
_CleanupExpiredListeners();
for (auto& weakListener : m_listeners) {
if (auto listener = weakListener.lock()) {
try {
listener->OnCameraParamChanged(cameraIndex, cameraParam);
} catch (const std::exception& e) {
LOG_ERROR("Exception in camera param change listener: %s\n", e.what());
}
}
}
}
void _NotifyAlgorithmParamChanged()
{
VrAlgorithmParams algorithmParams = GetAlgorithmParams();
std::lock_guard<std::mutex> lock(m_listenersMutex);
_CleanupExpiredListeners();
for (auto& weakListener : m_listeners) {
if (auto listener = weakListener.lock()) {
try {
listener->OnAlgorithmParamChanged(algorithmParams);
} catch (const std::exception& e) {
LOG_ERROR("Exception in algorithm param change listener: %s\n", e.what());
}
}
}
}
void _CleanupExpiredListeners()
{
// 移除已过期的weak_ptr
m_listeners.erase(
std::remove_if(m_listeners.begin(), m_listeners.end(),
[](const std::weak_ptr<IConfigChangeListener>& weak_listener) {
return weak_listener.expired();
}),
m_listeners.end());
}
// 初始化相关(子类可重写以提供自定义默认配置)
virtual bool _InitializeDefaultConfig()
{
std::lock_guard<std::mutex> lock(m_configMutex);
// 初始化默认ConfigResult
m_systemConfig.configResult = ConfigResult();
// 添加默认相机配置
DeviceInfo defaultCamera;
defaultCamera.name = "Camera1";
defaultCamera.ip = "192.168.1.100";
m_systemConfig.configResult.cameraList.push_back(defaultCamera);
// 初始化默认相机UI参数
m_systemConfig.cameraUIParams.clear();
CameraUIParam defaultCameraUI;
defaultCameraUI.cameraIndex = 1;
m_systemConfig.cameraUIParams.push_back(defaultCameraUI);
LOG_INFO("Default configuration initialized\n");
return true;
}
// 应用加载的配置(提取公共逻辑)
bool _ApplyLoadedConfig(const ConfigResult& configResult, const std::string& filePath)
{
std::lock_guard<std::mutex> lock(m_configMutex);
m_systemConfig.configResult = configResult;
// 初始化默认的相机UI参数
m_systemConfig.cameraUIParams.clear();
for (size_t i = 0; i < configResult.cameraList.size(); ++i) {
CameraUIParam cameraParam;
cameraParam.cameraIndex = static_cast<int>(i + 1);
m_systemConfig.cameraUIParams.push_back(cameraParam);
}
// 如果没有相机配置,至少添加一个默认相机
if (m_systemConfig.cameraUIParams.empty()) {
CameraUIParam defaultCamera;
defaultCamera.cameraIndex = 1;
m_systemConfig.cameraUIParams.push_back(defaultCamera);
}
LOG_INFO("Configuration loaded from file: %s\n", filePath.c_str());
return true;
}
};
#endif // BASECONFIGMANAGER_H