2026-04-07 19:41:28 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include <QObject>
|
|
|
|
|
#include <QProcess>
|
|
|
|
|
#include <QString>
|
|
|
|
|
|
2026-06-10 20:58:43 +02:00
|
|
|
class QLocalServer;
|
|
|
|
|
|
2026-04-07 19:41:28 +02:00
|
|
|
class ViewModuleHost : public QObject {
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
public:
|
|
|
|
|
explicit ViewModuleHost(QObject* parent = nullptr);
|
|
|
|
|
~ViewModuleHost();
|
|
|
|
|
|
2026-06-10 20:58:43 +02:00
|
|
|
bool spawn(const QString& moduleName, const QString& pluginPath,
|
|
|
|
|
const QString& authToken);
|
2026-04-07 19:41:28 +02:00
|
|
|
void stop();
|
|
|
|
|
bool isRunning() const;
|
|
|
|
|
QString socketName() const;
|
|
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
void processExited(int exitCode);
|
|
|
|
|
void ready();
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
QProcess* m_process = nullptr;
|
2026-06-10 20:58:43 +02:00
|
|
|
QLocalServer* m_tokenServer = nullptr;
|
2026-04-07 19:41:28 +02:00
|
|
|
QString m_moduleName;
|
|
|
|
|
QString m_socketName;
|
|
|
|
|
QByteArray m_stdoutBuffer;
|
|
|
|
|
bool m_readyEmitted = false;
|
2026-08-11 14:49:08 -03:00
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
|
// The child's MAIN THREAD id, which is what stop() posts WM_QUIT to.
|
|
|
|
|
// QProcess does not expose it directly, but CreateProcessArguments carries
|
|
|
|
|
// the PROCESS_INFORMATION pointer it hands to CreateProcess -- capture the
|
|
|
|
|
// pointer in the modifier (which runs BEFORE CreateProcess, so dwThreadId is
|
|
|
|
|
// not filled in yet) and read it once started() has fired.
|
|
|
|
|
//
|
|
|
|
|
// m_procInfo is owned by QProcess and deleted in its cleanup(); it is nulled
|
|
|
|
|
// as soon as started() reads through it and is never dereferenced elsewhere.
|
|
|
|
|
void* m_procInfo = nullptr;
|
|
|
|
|
unsigned long m_mainThreadId = 0; // DWORD
|
|
|
|
|
#endif
|
2026-04-07 19:41:28 +02:00
|
|
|
};
|