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/streamfsm.cpp

92 lines
1.8 KiB
C++

#include "streamfsm.h"
StreamFsm::StreamFsm(RestartPolicy policy, QObject *parent)
: QObject(parent)
, m_policy(policy)
{
}
StreamFsm::~StreamFsm()
{
stop();
}
void StreamFsm::start(const QString &program, const QStringList &args)
{
m_program = program;
m_args = args;
if (m_state == Idle)
startProcess();
}
void StreamFsm::stop()
{
if (m_state == Idle)
return;
if (m_proc) {
// Disconnect before killing so onFinished doesn't fire during teardown.
m_proc->disconnect();
m_proc->kill();
m_proc->waitForFinished(1000);
m_proc->deleteLater();
m_proc = nullptr;
}
transitTo(Idle);
}
void StreamFsm::setGuard(std::function<bool()> guard)
{
m_guard = std::move(guard);
}
void StreamFsm::startProcess()
{
if (m_state != Idle)
return;
m_proc = new QProcess(this);
connect(m_proc, &QProcess::readyReadStandardOutput,
this, &StreamFsm::onReadyRead);
connect(m_proc,
QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &StreamFsm::onFinished);
m_proc->start(m_program, m_args);
transitTo(Running);
}
void StreamFsm::onReadyRead()
{
QByteArray data = m_proc->readAllStandardOutput();
if (!data.isEmpty())
emit readyRead(data);
}
void StreamFsm::onFinished(int, QProcess::ExitStatus)
{
// Clean up the finished process.
m_proc->deleteLater();
m_proc = nullptr;
transitTo(Idle);
// Decide what to do next based on policy.
switch (m_policy) {
case Oneshot:
emit died();
break;
case Looping:
startProcess();
break;
case Guarded:
if (m_guard && m_guard())
startProcess();
else
emit died();
break;
}
}
void StreamFsm::transitTo(State s)
{
m_state = s;
}