Merge pull request #504 from aws-lumberyard-dev/Atom/guthadam/ATOM-15439
ATOM-15439 Implement basic local socket and server for IPC in material editor and other tools
This commit is contained in:
@@ -33,6 +33,7 @@ ly_add_target(
|
||||
AZ::AzQtComponents
|
||||
3rdParty::Qt::Core
|
||||
3rdParty::Qt::Gui
|
||||
3rdParty::Qt::Network
|
||||
3rdParty::Qt::Widgets
|
||||
3rdParty::Python
|
||||
Gem::Atom_RPI.Edit
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/std/functional.h>
|
||||
#include <QByteArray>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
//! A named local server that will manage connections and forward recieved data
|
||||
class LocalServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LocalServer();
|
||||
~LocalServer();
|
||||
|
||||
//! Start a named local server
|
||||
bool Connect(const QString& serverName);
|
||||
|
||||
//! Stop the server
|
||||
void Disconnect();
|
||||
|
||||
//! Get server status
|
||||
bool IsConnected() const;
|
||||
|
||||
using ReadHandler = AZStd::function<void(const QByteArray&)>;
|
||||
|
||||
//! Set a handler that recieved data will be forwarded to
|
||||
void SetReadHandler(ReadHandler handler);
|
||||
|
||||
private:
|
||||
void AddConnection(QLocalSocket* connection);
|
||||
void ReadFromConnection(QLocalSocket* connection);
|
||||
void DeleteConnection(QLocalSocket* connection);
|
||||
|
||||
QString m_serverName;
|
||||
QLocalServer m_server;
|
||||
ReadHandler m_readHandler;
|
||||
};
|
||||
} // namespace AtomToolsFramework
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <QLocalSocket>
|
||||
#endif
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
//! LocalSocket enables interprocess communication by establ;ishing a connection and sending data to a LocalServer
|
||||
class LocalSocket : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LocalSocket();
|
||||
~LocalSocket();
|
||||
|
||||
//! Attempt to connect to a named local server
|
||||
bool Connect(const QString& serverName);
|
||||
|
||||
//! Sever connection from server
|
||||
void Disconnect();
|
||||
|
||||
//! Get the sockets connection status
|
||||
bool IsConnected() const;
|
||||
|
||||
//! Send a stream of data to the connected local server
|
||||
bool Send(const QByteArray& buffer);
|
||||
|
||||
private:
|
||||
QString m_serverName;
|
||||
QLocalSocket m_socket;
|
||||
};
|
||||
} // namespace AtomToolsFramework
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomToolsFramework/Communication/LocalServer.h>
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <QString>
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
LocalServer::LocalServer()
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Creating local server\n");
|
||||
m_server.setSocketOptions(QLocalServer::WorldAccessOption);
|
||||
|
||||
QObject::connect(&m_server, &QLocalServer::newConnection, this, [this]() { AddConnection(m_server.nextPendingConnection()); });
|
||||
}
|
||||
|
||||
LocalServer::~LocalServer()
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
bool LocalServer::Connect(const QString& serverName)
|
||||
{
|
||||
Disconnect();
|
||||
|
||||
m_serverName = serverName;
|
||||
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Starting: %s\n", m_serverName.toUtf8().constData());
|
||||
if (m_server.listen(m_serverName))
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Started: %s\n", m_serverName.toUtf8().constData());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_server.serverError() == QAbstractSocket::AddressInUseError)
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Restarting: %s\n", m_serverName.toUtf8().constData());
|
||||
Disconnect();
|
||||
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Starting: %s\n", m_serverName.toUtf8().constData());
|
||||
if (m_server.listen(m_serverName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Starting failed: %s\n", m_serverName.toUtf8().constData());
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
void LocalServer::Disconnect()
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Disconnecting: %s\n", m_serverName.toUtf8().constData());
|
||||
QLocalServer::removeServer(m_serverName);
|
||||
}
|
||||
|
||||
bool LocalServer::IsConnected() const
|
||||
{
|
||||
return m_server.isListening();
|
||||
}
|
||||
|
||||
void LocalServer::SetReadHandler(LocalServer::ReadHandler handler)
|
||||
{
|
||||
m_readHandler = handler;
|
||||
}
|
||||
|
||||
void LocalServer::AddConnection(QLocalSocket* connection)
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Connection added: %s\n", m_serverName.toUtf8().constData());
|
||||
QObject::connect(connection, &QLocalSocket::readyRead, this, [this, connection]() { ReadFromConnection(connection); });
|
||||
QObject::connect(connection, &QLocalSocket::disconnected, this, [this, connection]() { DeleteConnection(connection); });
|
||||
}
|
||||
|
||||
void LocalServer::ReadFromConnection(QLocalSocket* connection)
|
||||
{
|
||||
if (connection)
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Data received: %s\n", m_serverName.toUtf8().constData());
|
||||
QByteArray buffer = connection->readAll();
|
||||
if (m_readHandler)
|
||||
{
|
||||
m_readHandler(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LocalServer::DeleteConnection(QLocalSocket* connection)
|
||||
{
|
||||
if (connection)
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalServer", "Deleting connection: %s\n", m_serverName.toUtf8().constData());
|
||||
connection->deleteLater();
|
||||
}
|
||||
}
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
#include <AtomToolsFramework/Communication/moc_LocalServer.cpp>
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
|
||||
* its licensors.
|
||||
*
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this
|
||||
* distribution (the "License"). All use of this software is governed by the License,
|
||||
* or, if provided, by the license below or the license accompanying this file. Do not
|
||||
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AtomToolsFramework/Communication/LocalSocket.h>
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
|
||||
namespace AtomToolsFramework
|
||||
{
|
||||
LocalSocket::LocalSocket()
|
||||
{
|
||||
}
|
||||
|
||||
LocalSocket::~LocalSocket()
|
||||
{
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
bool LocalSocket::Connect(const QString& serverName)
|
||||
{
|
||||
Disconnect();
|
||||
|
||||
m_serverName = serverName;
|
||||
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Connecting to: %s\n", m_serverName.toUtf8().constData());
|
||||
m_socket.connectToServer(m_serverName);
|
||||
|
||||
if (IsConnected())
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Waiting for connection to: %s\n", m_serverName.toUtf8().constData());
|
||||
if (m_socket.waitForConnected())
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Connected to: %s\n", m_serverName.toUtf8().constData());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Connecting failed: %s\n", m_serverName.toUtf8().constData());
|
||||
Disconnect();
|
||||
return false;
|
||||
}
|
||||
|
||||
void LocalSocket::Disconnect()
|
||||
{
|
||||
if (IsConnected())
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Disconnecting from: %s\n", m_serverName.toUtf8().constData());
|
||||
m_socket.disconnectFromServer();
|
||||
m_socket.waitForDisconnected();
|
||||
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Closing socket\n");
|
||||
m_socket.close();
|
||||
}
|
||||
}
|
||||
|
||||
bool LocalSocket::IsConnected() const
|
||||
{
|
||||
return m_socket.isOpen();
|
||||
}
|
||||
|
||||
bool LocalSocket::Send(const QByteArray& buffer)
|
||||
{
|
||||
if (IsConnected())
|
||||
{
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Sending data to: %s\n", m_serverName.toUtf8().constData());
|
||||
m_socket.write(buffer);
|
||||
|
||||
AZ_TracePrintf("AtomToolsFramework::LocalSocket", "Waiting for write to: %s\n", m_serverName.toUtf8().constData());
|
||||
m_socket.waitForBytesWritten();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace AtomToolsFramework
|
||||
|
||||
#include <AtomToolsFramework/Communication/moc_LocalSocket.cpp>
|
||||
@@ -10,6 +10,8 @@
|
||||
#
|
||||
|
||||
set(FILES
|
||||
Include/AtomToolsFramework/Communication/LocalServer.h
|
||||
Include/AtomToolsFramework/Communication/LocalSocket.h
|
||||
Include/AtomToolsFramework/Debug/TraceRecorder.h
|
||||
Include/AtomToolsFramework/DynamicProperty/DynamicProperty.h
|
||||
Include/AtomToolsFramework/DynamicProperty/DynamicPropertyGroup.h
|
||||
@@ -22,6 +24,8 @@ set(FILES
|
||||
Include/AtomToolsFramework/Util/MaterialPropertyUtil.h
|
||||
Include/AtomToolsFramework/Util/Util.h
|
||||
Include/AtomToolsFramework/Viewport/RenderViewportWidget.h
|
||||
Source/Communication/LocalServer.cpp
|
||||
Source/Communication/LocalSocket.cpp
|
||||
Source/Debug/TraceRecorder.cpp
|
||||
Source/DynamicProperty/DynamicProperty.cpp
|
||||
Source/DynamicProperty/DynamicPropertyGroup.cpp
|
||||
|
||||
Reference in New Issue
Block a user