// This file was generated with the assistance of an AI coding tool.
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see . *
* *
********************************************************************************/
#ifndef IFCINTERFACE_MODULES_CONNECTORS_PROCESS_H
#define IFCINTERFACE_MODULES_CONNECTORS_PROCESS_H
#include "Discovery.h"
#include
#include
#include
#include
#include
#include
#include
namespace ifcviewerfull::modules::connectors {
// One running connector subprocess. Owns the QProcess, frames stdio as
// newline-delimited JSON-RPC 2.0, and routes responses back to per-call
// callbacks. Per the protocol, one process per session: launch lazily on
// first call(), keep alive until shutdown().
class ConnectorProcess : public QObject {
Q_OBJECT
public:
using ResultHandler = std::function;
using ErrorHandler = std::function;
explicit ConnectorProcess(ConnectorManifest manifest, QObject* parent = nullptr);
~ConnectorProcess() override;
const ConnectorManifest& manifest() const { return manifest_; }
bool isRunning() const;
QString lastError() const { return last_error_; }
// Lazy-launches the underlying process. Returns false on launch failure;
// the user-facing reason is in lastError().
bool ensureStarted();
// Async JSON-RPC 2.0 call. Exactly one of on_result / on_error fires
// exactly once, on the same thread (queued). Launch failure synthesizes
// an immediate on_error via singleShot so callers see consistent
// async ordering.
void call(const QString& method,
const QJsonValue& params,
ResultHandler on_result,
ErrorHandler on_error);
// Closes stdin and waits a few seconds for clean exit; SIGKILLs on
// timeout. Any in-flight calls fail via on_error. Safe to call when
// not running.
void shutdown();
signals:
// Process exited unexpectedly (not via shutdown()). In-flight calls have
// already been failed via on_error before this fires.
void crashed(const QString& message);
private:
void onReadyReadStdout();
void onProcessFinished(int exit_code, QProcess::ExitStatus status);
void dispatchLine(const QByteArray& line);
void failPendingAndClear(int code, const QString& message);
ConnectorManifest manifest_;
QProcess* process_ = nullptr;
QByteArray buffer_;
QString last_error_;
bool shutting_down_ = false;
quint64 next_request_id_ = 0;
struct Pending {
ResultHandler on_result;
ErrorHandler on_error;
};
QHash pending_;
};
} // namespace ifcviewerfull::modules::connectors
#endif