134 lines
4.0 KiB
C++
134 lines
4.0 KiB
C++
#include "mainwindow.h"
|
||
#include "SingleInstanceManager.h"
|
||
#include "AuthView.h"
|
||
#include "AuthManager.h"
|
||
#include "HolePitPositionPresenter.h"
|
||
#include "IYHolePitPositionStatus.h"
|
||
#include "VrLog.h"
|
||
|
||
#include <QApplication>
|
||
#include <QIcon>
|
||
#include <QMessageBox>
|
||
#include <QObject>
|
||
#include <cstdio>
|
||
#include <cstring>
|
||
|
||
#ifdef Q_OS_UNIX
|
||
#include <cstdlib>
|
||
#include <sys/stat.h>
|
||
#endif
|
||
|
||
// 无桌面模式下的状态监听器,将状态信息输出到日志
|
||
class HeadlessStatusListener : public IYHolePitPositionStatus
|
||
{
|
||
public:
|
||
void OnStatusUpdate(const std::string& msg) override {
|
||
LOG_INFO("[Headless] Status: %s\n", msg.c_str());
|
||
}
|
||
void OnDetectionResult(const HolePitPositionResult& result) override {
|
||
LOG_INFO("[Headless] DetectionResult received, errorCode=%d\n", result.errorCode);
|
||
}
|
||
void OnCamera1StatusChanged(bool connected) override {
|
||
LOG_INFO("[Headless] Camera1: %s\n", connected ? "connected" : "disconnected");
|
||
}
|
||
void OnCamera2StatusChanged(bool connected) override {
|
||
LOG_INFO("[Headless] Camera2: %s\n", connected ? "connected" : "disconnected");
|
||
}
|
||
void OnRobotConnectionChanged(bool connected) override {
|
||
LOG_INFO("[Headless] Robot: %s\n", connected ? "connected" : "disconnected");
|
||
}
|
||
void OnSerialConnectionChanged(bool connected) override {
|
||
LOG_INFO("[Headless] Serial: %s\n", connected ? "connected" : "disconnected");
|
||
}
|
||
void OnCameraCountChanged(int count) override {
|
||
LOG_INFO("[Headless] CameraCount: %d\n", count);
|
||
}
|
||
void OnWorkStatusChanged(WorkStatus status) override {
|
||
LOG_INFO("[Headless] WorkStatus changed: %d\n", static_cast<int>(status));
|
||
}
|
||
};
|
||
|
||
#ifdef Q_OS_UNIX
|
||
// 检测设备文件是否存在
|
||
static bool deviceExists(const char* path)
|
||
{
|
||
struct stat st;
|
||
return stat(path, &st) == 0;
|
||
}
|
||
|
||
// 检测是否有可用的显示设备(X11、Wayland、framebuffer、DRM 任意一种即可)
|
||
static bool detectDisplay()
|
||
{
|
||
// X11 / Wayland 环境变量
|
||
const char* display = std::getenv("DISPLAY");
|
||
const char* waylandDisp = std::getenv("WAYLAND_DISPLAY");
|
||
if ((display && strlen(display) > 0) ||
|
||
(waylandDisp && strlen(waylandDisp) > 0)) {
|
||
return true;
|
||
}
|
||
|
||
// Framebuffer(嵌入式 ARM 常见)
|
||
if (deviceExists("/dev/fb0")) {
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
#endif
|
||
|
||
int main(int argc, char *argv[])
|
||
{
|
||
bool hasDisplay = true;
|
||
#ifdef Q_OS_UNIX
|
||
hasDisplay = detectDisplay();
|
||
if (!hasDisplay) {
|
||
qputenv("QT_QPA_PLATFORM", "offscreen");
|
||
fprintf(stderr, "[Main] No display detected, running in headless mode.\n");
|
||
fflush(stderr);
|
||
}
|
||
#endif
|
||
|
||
QApplication a(argc, argv);
|
||
|
||
SingleInstanceManager instanceManager("HolePitPositionApp_SingleInstance_Key");
|
||
|
||
if (hasDisplay) {
|
||
// ---- 有桌面:完整 UI 模式 ----
|
||
a.setWindowIcon(QIcon(":/common/resource/logo.png"));
|
||
|
||
if (instanceManager.isAnotherInstanceRunning()) {
|
||
QMessageBox::information(nullptr,
|
||
QObject::tr("应用程序已运行"),
|
||
QObject::tr("坑孔定位检测应用程序已经在运行中,请勿重复启动!"),
|
||
QMessageBox::Ok);
|
||
return 0;
|
||
}
|
||
|
||
if (!AuthView::CheckAndShow(nullptr)) {
|
||
return 0;
|
||
}
|
||
|
||
MainWindow w;
|
||
w.show();
|
||
return a.exec();
|
||
} else {
|
||
// ---- 无桌面:只启动业务逻辑 ----
|
||
if (instanceManager.isAnotherInstanceRunning()) {
|
||
return 0;
|
||
}
|
||
|
||
// 无UI模式下直接检查授权有效性
|
||
if (!AuthManager::CheckLicenseValid()) {
|
||
fprintf(stderr, "[Main] Authorization check failed, exiting.\n");
|
||
fflush(stderr);
|
||
return 0;
|
||
}
|
||
|
||
static HeadlessStatusListener listener;
|
||
static HolePitPositionPresenter presenter;
|
||
presenter.SetStatusCallback<IYHolePitPositionStatus>(&listener);
|
||
presenter.Init();
|
||
return a.exec();
|
||
}
|
||
}
|