mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-04-27 07:48:01 -07:00
Rework
Took 30 minutes
This commit is contained in:
parent
a9b4be3014
commit
04665e4dd8
3 changed files with 94 additions and 43 deletions
|
|
@ -348,5 +348,5 @@ int main(int argc, char *argv[])
|
|||
CountryPixmapGenerator::clear();
|
||||
UserLevelPixmapGenerator::clear();
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1,90 @@
|
|||
#include "single_instance_manager.h"
|
||||
|
||||
SingleInstanceManager::SingleInstanceManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool SingleInstanceManager::tryRun(const QStringList &initialFiles)
|
||||
{
|
||||
serverName = "CockatriceSingleInstance";
|
||||
|
||||
QLocalSocket socket;
|
||||
socket.connectToServer(serverName);
|
||||
|
||||
if (socket.waitForConnected(200)) {
|
||||
// Serialize into buffer first
|
||||
QByteArray payload;
|
||||
QDataStream out(&payload, QIODevice::WriteOnly);
|
||||
out << initialFiles;
|
||||
|
||||
// Prefix with size
|
||||
QByteArray message;
|
||||
QDataStream msgStream(&message, QIODevice::WriteOnly);
|
||||
msgStream << quint32(payload.size());
|
||||
message.append(payload);
|
||||
|
||||
socket.write(message);
|
||||
socket.flush();
|
||||
socket.waitForBytesWritten(1000);
|
||||
|
||||
return false; // Another instance is running
|
||||
}
|
||||
|
||||
// No other instance → start server
|
||||
server = new QLocalServer(this);
|
||||
|
||||
connect(server, &QLocalServer::newConnection, this, &SingleInstanceManager::handleNewConnection);
|
||||
|
||||
if (!server->listen(serverName)) {
|
||||
QLocalServer::removeServer(serverName);
|
||||
server->listen(serverName);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
void SingleInstanceManager::handleNewConnection()
|
||||
{
|
||||
QLocalSocket *socket = server->nextPendingConnection();
|
||||
|
||||
// Per-connection state
|
||||
auto buffer = new QByteArray();
|
||||
auto expectedSize = new quint32(0);
|
||||
|
||||
connect(socket, &QLocalSocket::readyRead, this, [this, socket, buffer, expectedSize]() {
|
||||
buffer->append(socket->readAll());
|
||||
|
||||
QDataStream stream(buffer, QIODevice::ReadOnly);
|
||||
|
||||
while (true) {
|
||||
// Step 1: read size
|
||||
if (*expectedSize == 0) {
|
||||
if (buffer->size() < static_cast<int>(sizeof(quint32)))
|
||||
return;
|
||||
|
||||
stream >> *expectedSize;
|
||||
}
|
||||
|
||||
// Step 2: wait for full payload
|
||||
if (buffer->size() < static_cast<int>(sizeof(quint32) + *expectedSize))
|
||||
return;
|
||||
|
||||
// Step 3: extract payload
|
||||
QByteArray payload = buffer->mid(sizeof(quint32), *expectedSize);
|
||||
|
||||
QDataStream payloadStream(&payload, QIODevice::ReadOnly);
|
||||
QStringList files;
|
||||
payloadStream >> files;
|
||||
|
||||
emit filesReceived(files);
|
||||
|
||||
// Reset buffer (single message use-case)
|
||||
buffer->clear();
|
||||
*expectedSize = 0;
|
||||
|
||||
socket->disconnectFromServer();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
connect(socket, &QLocalSocket::disconnected, socket, &QLocalSocket::deleteLater);
|
||||
}
|
||||
|
|
@ -10,57 +10,19 @@ class SingleInstanceManager : public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SingleInstanceManager(QObject *parent = nullptr) : QObject(parent)
|
||||
{
|
||||
}
|
||||
explicit SingleInstanceManager(QObject *parent = nullptr);
|
||||
|
||||
bool tryRun(const QStringList &initialFiles)
|
||||
{
|
||||
serverName = "CockatriceSingleInstance";
|
||||
|
||||
QLocalSocket socket;
|
||||
socket.connectToServer(serverName);
|
||||
if (socket.waitForConnected(100)) {
|
||||
// Another instance is running, send files/URLs to it
|
||||
QDataStream out(&socket);
|
||||
out << initialFiles;
|
||||
socket.flush();
|
||||
socket.waitForBytesWritten(1000);
|
||||
|
||||
return false; // Do not continue in this process
|
||||
}
|
||||
|
||||
// No other instance, create server
|
||||
server = new QLocalServer(this);
|
||||
connect(server, &QLocalServer::newConnection, this, &SingleInstanceManager::receiveFiles);
|
||||
if (!server->listen(serverName)) {
|
||||
QLocalServer::removeServer(serverName);
|
||||
server->listen(serverName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool tryRun(const QStringList &initialFiles);
|
||||
|
||||
signals:
|
||||
void filesReceived(const QStringList &files);
|
||||
|
||||
private slots:
|
||||
void receiveFiles()
|
||||
{
|
||||
QLocalSocket *clientConnection = server->nextPendingConnection();
|
||||
connect(clientConnection, &QLocalSocket::disconnected, clientConnection, &QLocalSocket::deleteLater);
|
||||
clientConnection->waitForReadyRead(1000);
|
||||
|
||||
QDataStream in(clientConnection);
|
||||
QStringList files;
|
||||
in >> files;
|
||||
|
||||
emit filesReceived(files);
|
||||
clientConnection->disconnectFromServer();
|
||||
}
|
||||
void handleNewConnection();
|
||||
|
||||
private:
|
||||
QString serverName;
|
||||
QLocalServer *server = nullptr;
|
||||
};
|
||||
|
||||
#endif // COCKATRICE_SINGLE_INSTANCE_MANAGER_H
|
||||
#endif // COCKATRICE_SINGLE_INSTANCE_MANAGER_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue