134 lines
4.0 KiB
C++
Raw Normal View History

2026-03-26 08:30:31 +08:00
#include "mainwindow.h"
#include "SingleInstanceManager.h"
#include "AuthView.h"
#include "AuthManager.h"
#include "HolePitPositionPresenter.h"
#include "IYHolePitPositionStatus.h"
#include "VrLog.h"
2026-03-26 08:30:31 +08:00
#include <QApplication>
#include <QIcon>
#include <QMessageBox>
#include <QObject>
#include <cstdio>
#include <cstring>
2026-03-26 08:30:31 +08:00
#ifdef Q_OS_UNIX
#include <cstdlib>
#include <sys/stat.h>
#endif
// 无桌面模式下的状态监听器,将状态信息输出到日志
class HeadlessStatusListener : public IYHolePitPositionStatus
2026-03-26 08:30:31 +08:00
{
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));
}
};
2026-03-26 08:30:31 +08:00
#ifdef Q_OS_UNIX
// 检测设备文件是否存在
static bool deviceExists(const char* path)
{
struct stat st;
return stat(path, &st) == 0;
}
2026-03-26 08:30:31 +08:00
// 检测是否有可用的显示设备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;
}
2026-03-26 08:30:31 +08:00
// Framebuffer嵌入式 ARM 常见)
if (deviceExists("/dev/fb0")) {
return true;
2026-03-26 08:30:31 +08:00
}
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);
2026-03-26 08:30:31 +08:00
}
#endif
QApplication a(argc, argv);
2026-03-26 08:30:31 +08:00
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;
}
2026-03-26 08:30:31 +08:00
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();
}
2026-03-26 08:30:31 +08:00
}