Files
eUi/src/Core/detProcess.hpp
T

158 lines
6.0 KiB
C++

#include <qthread.h>
#include <serviceManager.h>
#include <sql/qSqlBase.h>
#include <missionLoader.h>
#include <CLIManager.h>
#include <back/missionResultHandle.h>
#include <jsonRpcServer.h>
class detProcess : public QThread
{
public:
CsvWriter* _csvWriter = nullptr;
missionResultHandle* _missionResultHandle = nullptr;
ServiceManager _serviceManager;
CLIManager* _cliManager; // 命令行接口管理器
rpc::JsonRpcServer _rpcServer;
bool initOnce = false;
detProcess(SQLiteDB* dbIn, nlohmann::ordered_json& jsonIn, qtFuncBridge* bridgeIn):
db(dbIn),bridge(bridgeIn), missionJson(jsonIn){
}
~detProcess() {
safeShutdownDelete(_serviceManager._triggerManager);
safeShutdownDelete(_serviceManager._cameraManager);
safeDelete(_serviceManager._handleAiModelManager);
}
// 对普通指针的安全删除
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;
}
void init() {
// 创建/重建需要的服务模块,避免重复创建
if (!_serviceManager._imgSaveThreadManager) {
_serviceManager._imgSaveThreadManager = new imgSaveThreadManager(missionJson["imgSaveBasePath"]);
}
if (!_serviceManager._cameraManager) {
_serviceManager._cameraManager = new cameraManager(missionJson, bridge);
}
if (!_serviceManager._triggerManager) {
_serviceManager._triggerManager = new triggerManager(this, bridge, missionJson["Triggers"]);
}
if (initOnce == false) {
initOnce = true;
_csvWriter = new CsvWriter(db);
_serviceManager._detDataManager = new detDataManager();
_missionResultHandle = new missionResultHandle(bridge);
_serviceManager._missionResultHandle = _missionResultHandle;
_serviceManager.dataBase = db;
_serviceManager._csvWriter = _csvWriter;
// handleAiModelManager 与 CLI 等只在首次初始化创建
if (!_serviceManager._handleAiModelManager) {
_serviceManager._handleAiModelManager = new handleAiModelManager(missionJson, bridge);
}
connect(bridge, &qtFuncBridge::reInitConfig, this, [=]() {reinitConfig(); });
_cliManager = new CLIManager(&_serviceManager, bridge);
}
}
bool waitrForInitResult(serviceModule* ptr, int overtimeS = 999999) {
int overTimeMs = overtimeS * 1000;
int timecnt = 0;
while (timecnt <= overTimeMs) {
if (ptr->status != NotInit)
break;
QThread::msleep(100);
timecnt += 100;
}
if (timecnt > overTimeMs)
return false;
if (ptr->status == InitFailure)
return false;
return true;
}
// 重新初始化配置
void reinitConfig() {
// 停止并删除线程型模块
safeShutdownDelete(_serviceManager._cameraManager);
safeShutdownDelete(_serviceManager._triggerManager);
if (_serviceManager._handleAiModelManager) {
// try invoking stop if exists
QMetaObject::invokeMethod(_serviceManager._handleAiModelManager, "stop", Qt::DirectConnection);
safeDelete(_serviceManager._handleAiModelManager);
}
init();
if (!this->isRunning()) {
this->start();
} else {
qDebug() << "detProcess already running, init refreshed. run() should handle reloading if needed.";
}
}
// 初始化并运行主流程
void run() {
#if 1
_serviceManager._cameraManager->start();
_serviceManager._handleAiModelManager->start();
_serviceManager._triggerManager->start();
bool res1 = waitrForInitResult(_serviceManager._cameraManager);
bool res2 = waitrForInitResult(_serviceManager._handleAiModelManager);
bool res3 = waitrForInitResult(_serviceManager._triggerManager);
if (res1 == true && res2 == true && res3 == true) {
_missionLoader.loadMission(missionJson["missionDllPath"]);
_missionLoader.getmission(missionJson["missionDllPath"])->initBasic(
&_serviceManager,
missionJson["missionSettings"], bridge
);
_cliManager->initBasicPreset(_missionLoader.getmission(missionJson["missionDllPath"]));
_serviceManager._detDataManager->setTriggerManager(_serviceManager._triggerManager);
initJsonRpc();
emit bridge->initResult(InitOK);
}
else {
emit bridge->initResult(InitFailure);
}
#endif
}
void initJsonRpc() {
_rpcServer.registerMethod(QStringLiteral("reloadConfig"), [this](const nlohmann::json&) -> nlohmann::json {
_cliManager->cliCommand("reloadConfig");
std::cout << "接收到远程命令->重新加载配置文件" << std::endl;
return nlohmann::json{
{"result", "OK"}
};
});
// 检查服务器启动结果
_rpcServer.start(2367);
}
private:
nlohmann::ordered_json missionJson;
SQLiteDB* db;
qtFuncBridge* bridge;
MissionLoader _missionLoader; // 任务加载器,用于加载任务配置
};
#pragma once