1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include "resourceaccess.h"
#include "common/console.h"
#include "common/commands.h"
#include "common/commands/handshake_generated.h"
#include <QDebug>
#include <QProcess>
ResourceAccess::ResourceAccess(const QString &resourceName, QObject *parent)
: QObject(parent),
m_resourceName(resourceName),
m_socket(new QLocalSocket(this)),
m_tryOpenTimer(new QTimer(this)),
m_startingProcess(false)
{
m_tryOpenTimer->setInterval(50);
m_tryOpenTimer->setSingleShot(true);
connect(m_tryOpenTimer, &QTimer::timeout,
this, &ResourceAccess::open);
Console::main()->log(QString("Starting access to %1").arg(m_socket->serverName()));
connect(m_socket, &QLocalSocket::connected,
this, &ResourceAccess::connected);
connect(m_socket, &QLocalSocket::disconnected,
this, &ResourceAccess::disconnected);
connect(m_socket, SIGNAL(error(QLocalSocket::LocalSocketError)),
this, SLOT(connectionError(QLocalSocket::LocalSocketError)));
}
ResourceAccess::~ResourceAccess()
{
}
QString ResourceAccess::resourceName() const
{
return m_resourceName;
}
bool ResourceAccess::isReady() const
{
return m_socket->isValid();
}
void ResourceAccess::open()
{
if (m_socket->isValid()) {
Console::main()->log("Socket valid, so aborting the open");
return;
}
m_socket->setServerName(m_resourceName);
Console::main()->log(QString("Opening: %1").arg(m_socket->serverName()));
//FIXME: race between starting the exec and opening the socket?
m_socket->open();
}
void ResourceAccess::close()
{
Console::main()->log(QString("Closing: %1").arg(m_socket->fullServerName()));
m_socket->close();
}
void ResourceAccess::connected()
{
m_startingProcess = false;
Console::main()->log(QString("Connected: %1").arg(m_socket->fullServerName()));
{
flatbuffers::FlatBufferBuilder fbb;
auto name = fbb.CreateString("Client PID: " + QString::number((long long)this).toLatin1() + "!");
auto command = Toynadi::CreateHandshake(fbb, name);
Toynadi::FinishHandshakeBuffer(fbb, command);
const int commandId = Commands::HandshakeCommand;
const int dataSize = fbb.GetSize();
m_socket->write((const char*)&commandId, sizeof(int));
m_socket->write((const char*)&dataSize, sizeof(int));
m_socket->write((const char*)fbb.GetBufferPointer(), dataSize);
}
emit ready(true);
}
void ResourceAccess::disconnected()
{
m_socket->close();
Console::main()->log(QString("Disconnected: %1").arg(m_socket->fullServerName()));
emit ready(false);
open();
}
void ResourceAccess::connectionError(QLocalSocket::LocalSocketError error)
{
Console::main()->log(QString("Could not connect to %1 due to error %2").arg(m_socket->serverName()).arg(error));
if (m_startingProcess) {
if (!m_tryOpenTimer->isActive()) {
m_tryOpenTimer->start();
}
return;
}
m_startingProcess = true;
Console::main()->log(QString("Attempting to start resource..."));
QStringList args;
args << m_resourceName;
if (QProcess::startDetached("toynadi_resource", args)) {
m_socket->open();
}
}
|