2025-06-05 11:30:12 +08:00
|
|
|
#include <qthread.h>
|
2025-07-09 16:03:18 +08:00
|
|
|
#include <serviceManager.h>
|
2025-06-13 01:55:47 +08:00
|
|
|
#include <sql/qSqlBase.h>
|
|
|
|
|
#include <missonLoader.h>
|
2025-07-09 16:03:18 +08:00
|
|
|
#include <CLIManager.h>
|
2025-08-15 16:36:54 +08:00
|
|
|
#include <back/missionResultHandle.h>
|
2025-03-21 18:25:54 +08:00
|
|
|
class detProcess : public QThread
|
|
|
|
|
{
|
|
|
|
|
public:
|
2025-08-15 16:36:54 +08:00
|
|
|
CsvWriter* _csvWriter = nullptr;
|
|
|
|
|
missonResultHandle* _missonResultHandle = nullptr;
|
2025-07-09 16:03:18 +08:00
|
|
|
ServiceManager _serviceManager;
|
2025-08-20 16:57:03 +08:00
|
|
|
CLIManager* _cliManager; // 命令行接口管理器
|
2025-07-09 16:03:18 +08:00
|
|
|
bool initOnce = false;
|
2025-08-31 16:51:18 +08:00
|
|
|
detProcess(SQLiteDB* dbIn, nlohmann::ordered_json& jsonIn, qtFuncBridge* bridgeIn):
|
|
|
|
|
db(dbIn),bridge(bridgeIn),json(jsonIn){
|
|
|
|
|
|
2025-06-05 11:30:12 +08:00
|
|
|
}
|
2025-09-03 15:37:40 +08:00
|
|
|
|
|
|
|
|
// 对普通指针的安全删除
|
|
|
|
|
template<typename T>
|
|
|
|
|
void safeDelete(T*& ptr) {
|
|
|
|
|
if (ptr) { delete ptr; ptr = nullptr; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 尝试对基于 QThread 的 serviceModule 进行关停,然后删除
|
|
|
|
|
void safeShutdownDelete(serviceModule* ptr) {
|
|
|
|
|
if (!ptr) return;
|
|
|
|
|
// 如果对象正在运行,尝试停止
|
|
|
|
|
if (ptr->isRunning()) {
|
|
|
|
|
// 如果存在 stop 槽,则尝试调用
|
|
|
|
|
QMetaObject::invokeMethod(ptr, "stop", Qt::DirectConnection);
|
|
|
|
|
// 作为后备,尝试退出事件循环
|
|
|
|
|
QMetaObject::invokeMethod(ptr, "quit", Qt::DirectConnection);
|
|
|
|
|
// 等待其退出,给予一定时间
|
|
|
|
|
if (!ptr->wait(2000)) {
|
|
|
|
|
// 仍在运行时,作为最后手段强制终止
|
|
|
|
|
ptr->terminate();
|
|
|
|
|
ptr->wait(1000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
delete ptr; ptr = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-31 16:51:18 +08:00
|
|
|
void init() {
|
2025-09-03 15:37:40 +08:00
|
|
|
// 创建/重建需要的服务模块,避免重复创建
|
|
|
|
|
if (!_serviceManager._imgSaveThreadManager) {
|
|
|
|
|
_serviceManager._imgSaveThreadManager = new imgSaveThreadManager(json["imgSaveBasePath"]);
|
|
|
|
|
}
|
|
|
|
|
if (!_serviceManager._cameraManager) {
|
|
|
|
|
_serviceManager._cameraManager = new cameraManager(json, bridge);
|
|
|
|
|
}
|
|
|
|
|
if (!_serviceManager._triggerManager) {
|
|
|
|
|
_serviceManager._triggerManager = new triggerManager(this, bridge, json["Triggers"]);
|
|
|
|
|
}
|
2025-06-15 03:06:01 +08:00
|
|
|
if (initOnce == false) {
|
|
|
|
|
initOnce = true;
|
2025-08-31 16:51:18 +08:00
|
|
|
_csvWriter = new CsvWriter(db);
|
2025-09-03 15:37:40 +08:00
|
|
|
_serviceManager._detDataManager = new detDataManager();
|
2025-08-15 16:36:54 +08:00
|
|
|
_missonResultHandle = new missonResultHandle(bridge);
|
|
|
|
|
_serviceManager._missonResultHandle = _missonResultHandle;
|
2025-08-31 16:51:18 +08:00
|
|
|
_serviceManager.dataBase = db;
|
2025-08-15 16:36:54 +08:00
|
|
|
_serviceManager._csvWriter = _csvWriter;
|
2025-09-03 15:37:40 +08:00
|
|
|
// handleAiModelManager 与 CLI 等只在首次初始化创建
|
|
|
|
|
if (!_serviceManager._handleAiModelManager) {
|
|
|
|
|
_serviceManager._handleAiModelManager = new handleAiModelManager(json, bridge);
|
|
|
|
|
}
|
2025-08-31 16:51:18 +08:00
|
|
|
connect(bridge, &qtFuncBridge::reInitConfig, this, [=]() {reinitConfig(); });
|
|
|
|
|
_cliManager = new CLIManager(&_serviceManager, bridge);
|
2025-06-15 03:06:01 +08:00
|
|
|
}
|
2025-06-05 11:30:12 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool waitrForInitResult(serviceModule* ptr, int overtimeS = 999999) {
|
|
|
|
|
int overTimeMs = overtimeS * 1000;
|
2025-03-28 18:33:43 +08:00
|
|
|
int timecnt = 0;
|
2025-06-05 11:30:12 +08:00
|
|
|
while (timecnt <= overTimeMs) {
|
2025-03-28 18:33:43 +08:00
|
|
|
if (ptr->status != NotInit)
|
|
|
|
|
break;
|
|
|
|
|
QThread::msleep(100);
|
2025-06-05 11:30:12 +08:00
|
|
|
timecnt += 100;
|
2025-03-28 18:33:43 +08:00
|
|
|
}
|
|
|
|
|
if (timecnt > overTimeMs)
|
|
|
|
|
return false;
|
|
|
|
|
if (ptr->status == InitFailure)
|
|
|
|
|
return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-03-21 18:25:54 +08:00
|
|
|
|
2025-06-15 03:06:01 +08:00
|
|
|
// 重新初始化配置
|
|
|
|
|
void reinitConfig() {
|
2025-09-03 15:37:40 +08:00
|
|
|
// 1. 优雅停止并释放已有运行中的服务模块
|
|
|
|
|
// 停止并删除线程型模块
|
|
|
|
|
safeShutdownDelete(_serviceManager._cameraManager);
|
|
|
|
|
safeShutdownDelete(_serviceManager._triggerManager);
|
|
|
|
|
// imgSaveThreadManager 可能不是 QThread,直接删除
|
|
|
|
|
safeDelete(_serviceManager._imgSaveThreadManager);
|
|
|
|
|
// handleAiModelManager 可能运行在后台,优雅停止后删除
|
|
|
|
|
if (_serviceManager._handleAiModelManager) {
|
|
|
|
|
// try invoking stop if exists
|
|
|
|
|
QMetaObject::invokeMethod(_serviceManager._handleAiModelManager, "stop", Qt::DirectConnection);
|
|
|
|
|
safeDelete(_serviceManager._handleAiModelManager);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-15 03:06:01 +08:00
|
|
|
// 2. 重新初始化
|
2025-08-31 16:51:18 +08:00
|
|
|
init();
|
2025-09-03 15:37:40 +08:00
|
|
|
|
|
|
|
|
// 3. 如果 detProcess 尚未运行,则启动主线程;如果已在运行,run() 应自行管理子模块的重启
|
|
|
|
|
if (!this->isRunning()) {
|
|
|
|
|
this->start();
|
|
|
|
|
} else {
|
|
|
|
|
// 已在运行的话,可以发出信号或回调,通知 run 中重载配置(这里仅 log)
|
|
|
|
|
qDebug() << "detProcess already running, init refreshed. run() should handle reloading if needed.";
|
|
|
|
|
}
|
2025-06-15 03:06:01 +08:00
|
|
|
}
|
2025-06-05 11:30:12 +08:00
|
|
|
// 初始化并运行主流程
|
|
|
|
|
void run() {
|
|
|
|
|
#if 1
|
2025-07-25 00:29:52 +08:00
|
|
|
//_pythonLoader.cao();
|
2025-07-09 16:03:18 +08:00
|
|
|
_serviceManager._cameraManager->start();
|
|
|
|
|
_serviceManager._handleAiModelManager->start();
|
2025-03-21 18:25:54 +08:00
|
|
|
//_lightSourceManager.start();
|
2025-07-09 16:03:18 +08:00
|
|
|
_serviceManager._triggerManager->start();
|
|
|
|
|
bool res1 = waitrForInitResult(_serviceManager._cameraManager);
|
|
|
|
|
bool res2 = waitrForInitResult(_serviceManager._handleAiModelManager);
|
|
|
|
|
bool res3 = waitrForInitResult(_serviceManager._triggerManager);
|
2025-06-05 11:30:12 +08:00
|
|
|
|
2025-07-09 16:03:18 +08:00
|
|
|
if (res1 == true && res2 == true && res3 == true) {
|
2025-06-13 01:55:47 +08:00
|
|
|
_missionLoader.loadMission(json["missionDllPath"]);
|
2025-08-15 16:36:54 +08:00
|
|
|
_missionLoader.getMisson(json["missionDllPath"])->init(
|
2025-07-09 16:03:18 +08:00
|
|
|
&_serviceManager,
|
2025-08-31 16:51:18 +08:00
|
|
|
json["missionSettings"], bridge
|
2025-06-05 11:30:12 +08:00
|
|
|
);
|
2025-08-20 16:57:03 +08:00
|
|
|
_cliManager->initBasicPreset();
|
2025-09-03 15:37:40 +08:00
|
|
|
_serviceManager._detDataManager->setTriggerManager(_serviceManager._triggerManager);
|
2025-07-25 00:29:52 +08:00
|
|
|
emit bridge->initResult(InitOK);
|
2025-06-05 11:30:12 +08:00
|
|
|
}
|
|
|
|
|
else {
|
2025-07-25 00:29:52 +08:00
|
|
|
emit bridge->initResult(InitFailure);
|
2025-03-21 18:25:54 +08:00
|
|
|
}
|
2025-08-15 16:36:54 +08:00
|
|
|
//_missonResultHandle->test();
|
2025-03-27 18:36:54 +08:00
|
|
|
#endif
|
2025-03-21 18:25:54 +08:00
|
|
|
}
|
2025-06-05 11:30:12 +08:00
|
|
|
private:
|
2025-08-15 16:36:54 +08:00
|
|
|
nlohmann::ordered_json json;
|
2025-08-31 16:51:18 +08:00
|
|
|
SQLiteDB* db;
|
2025-06-05 11:30:12 +08:00
|
|
|
qtFuncBridge* bridge;
|
2025-06-13 01:55:47 +08:00
|
|
|
MissionLoader _missionLoader; // 任务加载器,用于加载任务配置
|
2025-08-20 16:57:03 +08:00
|
|
|
|
2025-03-21 18:25:54 +08:00
|
|
|
};
|
2025-06-05 11:30:12 +08:00
|
|
|
|
|
|
|
|
#pragma once
|