summaryrefslogtreecommitdiffstats
path: root/client/resourceaccess.cpp
blob: 4042219806058e269f850665dbadb0be2ea355c6 (plain)
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/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();
    }
}