This repository has been archived on 2026-08-16. You can view files and clone it, but cannot push or open issues or pull requests.
ollie-kde/gui/nativestreamer.cpp

132 lines
2.9 KiB
C++

#include "nativestreamer.h"
#include <QStandardPaths>
#include <QDebug>
QString NativeStreamer::ollie9pBin()
{
return QStandardPaths::findExecutable("ollie-9p");
}
QString NativeStreamer::serverAddr()
{
QString ns = qEnvironmentVariable("NAMESPACE");
if (ns.isEmpty()) {
// Plan 9 default: /tmp/ns.$USER.$DISPLAY
QString user = qEnvironmentVariable("USER");
QString display = qEnvironmentVariable("DISPLAY");
ns = "/tmp/ns." + user + "." + display;
}
return "unix!" + ns + "/ollie";
}
NativeStreamer::NativeStreamer(RestartPolicy policy, QObject *parent)
: QObject(parent)
, m_policy(policy)
{
m_restartTimer = new QTimer(this);
m_restartTimer->setSingleShot(true);
m_restartTimer->setInterval(500); // 500ms delay before restart
connect(m_restartTimer, &QTimer::timeout, this, [this]() {
if (!m_stopping && !m_path.isEmpty()) {
start(m_path);
}
});
}
NativeStreamer::~NativeStreamer()
{
stop();
}
void NativeStreamer::start(const QString &path)
{
if (m_process) {
stop();
}
m_path = path;
m_stopping = false;
m_process = new QProcess(this);
connect(m_process, &QProcess::readyReadStandardOutput, this, &NativeStreamer::onReadyRead);
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &NativeStreamer::onProcessFinished);
m_process->start(ollie9pBin(), {"-a", serverAddr(), "read", path});
}
void NativeStreamer::stop()
{
m_stopping = true;
m_restartTimer->stop();
if (m_process) {
disconnect(m_process, nullptr, this, nullptr);
if (m_process->state() != QProcess::NotRunning) {
m_process->kill();
m_process->waitForFinished(1000);
}
m_process->deleteLater();
m_process = nullptr;
}
}
bool NativeStreamer::isRunning() const
{
return m_process && m_process->state() == QProcess::Running;
}
void NativeStreamer::setGuard(std::function<bool()> guard)
{
m_guard = guard;
}
void NativeStreamer::onReadyRead()
{
if (m_process) {
QByteArray data = m_process->readAllStandardOutput();
if (!data.isEmpty()) {
emit dataReady(data);
}
}
}
void NativeStreamer::onProcessFinished(int exitCode, QProcess::ExitStatus status)
{
Q_UNUSED(exitCode)
Q_UNUSED(status)
if (m_process) {
m_process->deleteLater();
m_process = nullptr;
}
scheduleRestart();
}
void NativeStreamer::scheduleRestart()
{
if (m_stopping) {
return;
}
bool shouldRestart = false;
switch (m_policy) {
case Oneshot:
shouldRestart = false;
break;
case Looping:
shouldRestart = true;
break;
case Guarded:
shouldRestart = m_guard && m_guard();
break;
}
if (shouldRestart) {
m_restartTimer->start();
} else {
emit finished();
}
}