mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-14 19:18:55 -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();
|
CountryPixmapGenerator::clear();
|
||||||
UserLevelPixmapGenerator::clear();
|
UserLevelPixmapGenerator::clear();
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,90 @@
|
||||||
#include "single_instance_manager.h"
|
#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
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit SingleInstanceManager(QObject *parent = nullptr) : QObject(parent)
|
explicit SingleInstanceManager(QObject *parent = nullptr);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tryRun(const QStringList &initialFiles)
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void filesReceived(const QStringList &files);
|
void filesReceived(const QStringList &files);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void receiveFiles()
|
void handleNewConnection();
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString serverName;
|
QString serverName;
|
||||||
QLocalServer *server = nullptr;
|
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