Merge branch 'development' into Prefabs/SpawnableEntityAlias

This commit is contained in:
AMZN-koppersr
2021-11-08 10:10:06 -08:00
74 changed files with 1239 additions and 1794 deletions
@@ -11,7 +11,6 @@ OutlinerWidget #m_display_options
{
qproperty-icon: url(:/Menu/menu.svg);
qproperty-iconSize: 16px 16px;
qproperty-flat: true;
}
OutlinerWidget QWidget[PulseHighlight="true"]
@@ -457,8 +457,6 @@ void JobManagerWorkStealing::ProcessJobsInternal(ThreadInfo* info, Job* suspende
else
{
//attempt to steal a job from another thread's queue
AZ_PROFILE_SCOPE(AzCore, "JobManagerWorkStealing::ProcessJobsInternal:WorkStealing");
unsigned int numStealAttempts = 0;
const unsigned int maxStealAttempts = (unsigned int)m_workerThreads.size() * 3; //try every thread a few times before giving up
while (!job)
@@ -10,6 +10,8 @@
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzFramework/Process/ProcessWatcher.h>
#include <sys/types.h>
#include <unistd.h>
@@ -24,14 +26,20 @@ namespace AzFramework::AssetSystem::Platform
AZ::IO::FixedMaxPath assetProcessorPath{ executableDirectory };
// In Mac the Editor and game is within a bundle, so the path to the sibling app
// has to go up from the Contents/MacOS folder the binary is in
assetProcessorPath /= "../../../AssetProcessor.app";
assetProcessorPath /= "../../../AssetProcessor.app/Contents/MacOS/AssetProcessor";
assetProcessorPath = assetProcessorPath.LexicallyNormal();
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath =
AZ::IO::FixedMaxPath{engineRoot} / "bin" / AZ_TRAIT_OS_PLATFORM_NAME / AZ_BUILD_CONFIGURATION_TYPE / "AssetProcessor.app";
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
if (AZ::IO::FixedMaxPath installedBinariesPath;
settingsRegistry->Get(installedBinariesPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_InstalledBinaryFolder))
{
// Check for existence of one under a "bin" directory, i.e. engineRoot is an SDK structure.
assetProcessorPath = AZ::IO::FixedMaxPath{ engineRoot } / installedBinariesPath / "AssetProcessor.app/Contents/MacOS/AssetProcessor";
}
}
if (!AZ::IO::SystemFile::Exists(assetProcessorPath.c_str()))
{
@@ -39,23 +47,21 @@ namespace AzFramework::AssetSystem::Platform
}
}
auto fullLaunchCommand = AZ::IO::FixedMaxPathString::format(R"(open -g "%s" --args --start-hidden)", assetProcessorPath.c_str());
AZStd::string commandLineParams;
// Add the engine path to the launch command if not empty
if (!engineRoot.empty())
{
fullLaunchCommand += R"( --engine-path=")";
fullLaunchCommand += engineRoot;
fullLaunchCommand += '"';
commandLineParams += AZStd::string::format("\"--engine-path=\"%s\"\"", engineRoot.data());
}
// Add the active project path to the launch command if not empty
if (!projectPath.empty())
{
fullLaunchCommand += R"( --project-path=")";
fullLaunchCommand += projectPath;
fullLaunchCommand += '"';
commandLineParams += AZStd::string::format(" \"--regset=/Amazon/AzCore/Bootstrap/project_path=\"%s\"\"", projectPath.data());
}
return system(fullLaunchCommand.c_str()) == 0;
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
processLaunchInfo.m_processExecutableString = AZStd::move(assetProcessorPath.Native());
processLaunchInfo.m_commandlineParameters = commandLineParams;
return AzFramework::ProcessLauncher::LaunchUnwatchedProcess(processLaunchInfo);
}
}
@@ -13,7 +13,9 @@
<Member Type="AzNetworking::DisconnectReason" Name="disconnectReason" Init="AzNetworking::DisconnectReason::None" />
</Packet>
<Packet Name="HeartbeatPacket" Desc="This packet is used to keep an established connection alive" />
<Packet Name="HeartbeatPacket" Desc="This packet is used to keep an established connection alive">
<Member Type="bool" Name="requestResponse" Init="false" />
</Packet>
<Packet Name="FragmentedPacket" Desc="This packet is used to segment a packet that exceeds a connections MTU">
<Member Type="AzNetworking::SequenceId" Name="unfragmentedSequence" Init="AzNetworking::InvalidSequenceId" />
@@ -122,10 +122,4 @@ namespace AzNetworking
m_timeoutItemMap.erase(itemTimeoutId);
}
}
void TimeoutQueue::UpdateTimeouts(ITimeoutHandler& timeoutHandler, int32_t maxTimeouts)
{
TimeoutHandler handler([&timeoutHandler](TimeoutQueue::TimeoutItem& item) { return timeoutHandler.HandleTimeout(item); });
UpdateTimeouts(handler, maxTimeouts);
}
}
@@ -23,8 +23,6 @@ namespace AzNetworking
Delete
};
class ITimeoutHandler;
//! @class TimeoutQueue
//! @brief class for managing timeout items.
class TimeoutQueue
@@ -70,11 +68,6 @@ namespace AzNetworking
using TimeoutHandler = AZStd::function<TimeoutResult(TimeoutQueue::TimeoutItem&)>;
void UpdateTimeouts(const TimeoutHandler& timeoutHandler, int32_t maxTimeouts = -1);
//! Updates timeouts for all items, invokes timeout handlers if required.
//! @param timeoutHandler listener instance to call back on for timeouts
//! @param maxTimeouts the maximum number of timeouts to process before breaking iteration
void UpdateTimeouts(ITimeoutHandler& timeoutHandler, int32_t maxTimeouts = -1);
private:
struct TimeoutQueueItem
@@ -94,19 +87,6 @@ namespace AzNetworking
TimeoutItemMap m_timeoutItemMap;
TimeoutItemQueue m_timeoutItemQueue;
};
//! @class ITimeoutHandler
//! @brief interface class for managing timeout items.
class ITimeoutHandler
{
public:
virtual ~ITimeoutHandler() = default;
//! Handler callback for timed out items.
//! @param item containing registered timeout details
//! @return ETimeoutResult for whether to re-register or discard the timeout params
virtual TimeoutResult HandleTimeout(TimeoutQueue::TimeoutItem& item) = 0;
};
}
#include <AzNetworking/DataStructures/TimeoutQueue.inl>
@@ -27,13 +27,11 @@ namespace AzNetworking
ConnectionId connectionId,
const IpAddress& remoteAddress,
TcpNetworkInterface& networkInterface,
TcpSocket& socket,
TimeoutId timeoutId
TcpSocket& socket
)
: IConnection(connectionId, remoteAddress)
, m_networkInterface(networkInterface)
, m_socket(socket.CloneAndTakeOwnership())
, m_timeoutId(timeoutId)
, m_state(m_socket->IsOpen() ? ConnectionState::Connecting : ConnectionState::Disconnected)
, m_connectionRole(ConnectionRole::Acceptor)
, m_registeredSocketFd(InvalidSocketFd)
@@ -163,13 +161,6 @@ namespace AzNetworking
break;
}
TimeoutQueue::TimeoutItem* timeoutItem = m_networkInterface.m_connectionTimeoutQueue.RetrieveItem(GetTimeoutId());
if (timeoutItem == nullptr)
{
return true;
}
timeoutItem->UpdateTimeoutTime(startTimeMs);
NetworkOutputSerializer serializer(buffer.GetBuffer(), static_cast<uint32_t>(buffer.GetSize()));
if (m_state == ConnectionState::Connecting)
{
@@ -38,14 +38,12 @@ namespace AzNetworking
//! @param remoteAddress IP address of the remote endpoint
//! @param networkInterface TcpNetworkInterface that owns this connection instance
//! @param socket TCP socket to take ownership of and use for sending and receiving data
//! @param timeoutId timeout identifier of this connection instance
TcpConnection
(
ConnectionId connectionId,
const IpAddress& remoteAddress,
TcpNetworkInterface& networkInterface,
TcpSocket& socket,
TimeoutId timeoutId
TcpSocket& socket
);
//! Construct a new socket with optional encryption, used when initiating a new connection
@@ -69,14 +67,6 @@ namespace AzNetworking
//! @return the TcpSocket bound to this TcpConnection
TcpSocket* GetTcpSocket() const;
//! Sets the timeout identifier for this TcpConnection.
//! @param timeoutId the timeout identifier to use for this TcpConnection
void SetTimeoutId(TimeoutId timeoutId);
//! Returns the timeout identifier for this TcpConnection.
//! @return the timeout identifier for this TcpConnection
TimeoutId GetTimeoutId() const;
//! Returns true if this connection instance is in an open state, and is capable of actively sending and receiving packets.
//! @return boolean true if this connection instance is in an open state
bool IsOpen() const;
@@ -142,7 +132,6 @@ namespace AzNetworking
AZStd::unique_ptr<TcpSocket> m_socket;
AZStd::unique_ptr<ICompressor> m_compressor;
TimeoutId m_timeoutId;
PacketId m_lastSentPacketId = InvalidPacketId;
ConnectionState m_state = ConnectionState::Disconnected;
ConnectionRole m_connectionRole = ConnectionRole::Connector;
@@ -15,16 +15,6 @@ namespace AzNetworking
return m_socket.get();
}
inline void TcpConnection::SetTimeoutId(TimeoutId timeoutId)
{
m_timeoutId = timeoutId;
}
inline TimeoutId TcpConnection::GetTimeoutId() const
{
return m_timeoutId;
}
inline bool TcpConnection::IsOpen() const
{
return m_socket->IsOpen();
@@ -21,16 +21,11 @@ namespace AzNetworking
static const bool net_TcpUseEncryption = false;
#endif
AZ_CVAR(bool, net_TcpTimeoutConnections, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Boolean value on whether we should timeout Tcp connections");
AZ_CVAR(AZ::TimeMs, net_TcpHeartbeatTimeMs, AZ::TimeMs{ 2 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Tcp connection heartbeat frequency");
AZ_CVAR(AZ::TimeMs, net_TcpDefaultTimeoutMs, AZ::TimeMs{ 10 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Time in milliseconds before we timeout an idle Tcp connection");
TcpNetworkInterface::TcpNetworkInterface(AZ::Name name, IConnectionListener& connectionListener, TrustZone trustZone, TcpListenThread& listenThread)
: m_name(name)
, m_trustZone(trustZone)
, m_connectionListener(connectionListener)
, m_listenThread(listenThread)
, m_timeoutMs(net_TcpDefaultTimeoutMs)
{
;
}
@@ -98,8 +93,6 @@ namespace AzNetworking
}
AZLOG_INFO("Adding new socket %d", static_cast<int32_t>(tcpSocket->GetSocketFd()));
const TimeoutId newTimeoutId = m_connectionTimeoutQueue.RegisterItem(static_cast<uint64_t>(tcpSocket->GetSocketFd()), net_TcpHeartbeatTimeMs);
connection->SetTimeoutId(newTimeoutId);
connection->SendReliablePacket(CorePackets::InitiateConnectionPacket());
m_connectionListener.OnConnect(connection.get());
m_connectionSet.AddConnection(AZStd::move(connection));
@@ -110,12 +103,6 @@ namespace AzNetworking
{
const AZ::TimeMs startTimeMs = AZ::GetElapsedTimeMs();
// Time out any stale connections
{
ConnectionTimeoutFunctor functor(*this);
m_connectionTimeoutQueue.UpdateTimeouts(functor);
}
AcceptNewConnections();
auto readCallback = [this, startTimeMs](SocketFd socketFd) { HandleConnectionRecv(socketFd, startTimeMs); };
@@ -258,8 +245,7 @@ namespace AzNetworking
return;
}
AZLOG(NET_TcpTraffic, "Adding new socket %d", static_cast<int32_t>(tcpSocket.GetSocketFd()));
const TimeoutId timeoutId = m_connectionTimeoutQueue.RegisterItem(static_cast<uint64_t>(tcpSocket.GetSocketFd()), m_timeoutMs);
AZStd::unique_ptr<TcpConnection> connection = AZStd::make_unique<TcpConnection>(connectionId, remoteAddress, *this, tcpSocket, timeoutId);
AZStd::unique_ptr<TcpConnection> connection = AZStd::make_unique<TcpConnection>(connectionId, remoteAddress, *this, tcpSocket);
AZ_Assert(connection->GetConnectionRole() == ConnectionRole::Acceptor, "Invalid role for connection");
GetConnectionListener().OnConnect(connection.get());
m_connectionSet.AddConnection(AZStd::move(connection));
@@ -286,7 +272,6 @@ namespace AzNetworking
m_pendingRemoves.resize_no_construct(0);
}
TcpNetworkInterface::PendingConnection::PendingConnection(SocketFd socketFd, uint32_t remoteIpAddress, uint16_t remotePort, uint16_t listenPort)
: m_socketFd(socketFd)
, m_remoteIpAddress(remoteIpAddress)
@@ -295,34 +280,4 @@ namespace AzNetworking
{
;
}
TcpNetworkInterface::ConnectionTimeoutFunctor::ConnectionTimeoutFunctor(TcpNetworkInterface& networkInterface)
: m_networkInterface(networkInterface)
{
;
}
TimeoutResult TcpNetworkInterface::ConnectionTimeoutFunctor::HandleTimeout(TimeoutQueue::TimeoutItem& item)
{
const SocketFd socketFd = static_cast<SocketFd>(item.m_userData);
TcpConnection* tcpConnection = m_networkInterface.m_connectionSet.GetConnection(socketFd);
if (tcpConnection == nullptr)
{
// We've already deleted this connection
return TimeoutResult::Delete;
}
if (tcpConnection->GetConnectionRole() == ConnectionRole::Connector)
{
tcpConnection->SendReliablePacket(CorePackets::HeartbeatPacket());
}
else if (net_TcpTimeoutConnections && (m_networkInterface.GetTimeoutMs() > AZ::TimeMs{ 0 }))
{
tcpConnection->Disconnect(DisconnectReason::Timeout, TerminationEndpoint::Local);
return TimeoutResult::Delete;
}
return TimeoutResult::Refresh;
}
}
@@ -137,16 +137,6 @@ namespace AzNetworking
AZ_DISABLE_COPY_MOVE(TcpNetworkInterface);
struct ConnectionTimeoutFunctor final
: public ITimeoutHandler
{
ConnectionTimeoutFunctor(TcpNetworkInterface& networkInterface);
TimeoutResult HandleTimeout(TimeoutQueue::TimeoutItem& item) override;
private:
AZ_DISABLE_COPY_MOVE(ConnectionTimeoutFunctor);
TcpNetworkInterface& m_networkInterface;
};
struct PendingRemove
{
SocketFd m_socketFd;
@@ -162,7 +152,6 @@ namespace AzNetworking
TcpSocketManager m_tcpSocketManager;
AZ::ThreadSafeDeque<PendingConnection> m_pendingConnections;
AZStd::vector<PendingRemove> m_pendingRemoves;
TimeoutQueue m_connectionTimeoutQueue;
TcpListenThread& m_listenThread;
friend class TcpConnection; // For access to private RequestDisconnect() method
@@ -79,7 +79,8 @@ namespace AzNetworking
AZLOG(NET_Acks, "Unacked packet count exceeded, sending client heartbeat (curr %u : max %u)", m_unackedPacketCount, static_cast<uint32_t>(net_UdpMaxUnackedPacketCount));
// This simply times out unreliable chunks that haven't completed within our timeout delay
m_fragmentQueue.Update();
SendUnreliablePacket(CorePackets::HeartbeatPacket());
// This heartbeat is sent to minimize the time the remote endpoint spends waiting for ack vector replication, we don't require a response
SendUnreliablePacket(CorePackets::HeartbeatPacket(false));
}
}
@@ -289,7 +290,11 @@ namespace AzNetworking
{
return PacketDispatchResult::Failure;
}
// Do nothing, we've already processed our ack packets
if (packet.GetRequestResponse())
{
// We're replying to a heartbeat request, we don't want a response
SendUnreliablePacket(CorePackets::HeartbeatPacket(false));
}
return PacketDispatchResult::Success;
}
break;
@@ -136,12 +136,12 @@ namespace AzNetworking
AZ_DISABLE_COPY_MOVE(UdpConnection);
UdpNetworkInterface& m_networkInterface;
UdpPacketTracker m_packetTracker;
UdpReliableQueue m_reliableQueue;
UdpFragmentQueue m_fragmentQueue;
ConnectionState m_state = ConnectionState::Disconnected;
ConnectionRole m_connectionRole = ConnectionRole::Connector;
DtlsEndpoint m_dtlsEndpoint;
UdpPacketTracker m_packetTracker;
UdpReliableQueue m_reliableQueue;
UdpFragmentQueue m_fragmentQueue;
ConnectionState m_state = ConnectionState::Disconnected;
ConnectionRole m_connectionRole = ConnectionRole::Connector;
DtlsEndpoint m_dtlsEndpoint;
AZ::TimeMs m_lastSentPacketMs;
uint32_t m_unackedPacketCount = 0;
@@ -20,7 +20,13 @@ namespace AzNetworking
void UdpFragmentQueue::Update()
{
m_timeoutQueue.UpdateTimeouts(*this);
m_timeoutQueue.UpdateTimeouts([this](TimeoutQueue::TimeoutItem& item)
{
const SequenceId fragmentSequence = static_cast<SequenceId>(item.m_userData & 0xFF);
AZLOG(NET_FragmentQueue, "Timing out unreliable fragmented packet %u", static_cast<uint32_t>(fragmentSequence));
m_packetFragments.erase(fragmentSequence);
return TimeoutResult::Delete;
});
}
void UdpFragmentQueue::Reset()
@@ -163,12 +169,4 @@ namespace AzNetworking
return handledPacket;
}
TimeoutResult UdpFragmentQueue::HandleTimeout(TimeoutQueue::TimeoutItem& item)
{
const SequenceId fragmentSequence = static_cast<SequenceId>(item.m_userData & 0xFF);
AZLOG(NET_FragmentQueue, "Timing out unreliable fragmented packet %u", static_cast<uint32_t>(fragmentSequence));
m_packetFragments.erase(fragmentSequence);
return TimeoutResult::Delete;
}
}
@@ -26,7 +26,6 @@ namespace AzNetworking
//! @class UdpFragmentQueue
//! @brief Class for reconstructing packet chunks into the original unsegmented packet.
class UdpFragmentQueue
: public ITimeoutHandler
{
public:
@@ -51,11 +50,6 @@ namespace AzNetworking
private:
//! Handler callback for timed out items.
//! @param item containing registered timeout details
//! @return ETimeoutResult for whether to re-register or discard the timeout params
TimeoutResult HandleTimeout(TimeoutQueue::TimeoutItem& item) override;
TimeoutQueue m_timeoutQueue;
SequenceGenerator m_sequenceGenerator;
@@ -31,7 +31,7 @@ namespace AzNetworking
AZ_CVAR(bool, net_UdpTimeoutConnections, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Boolean value on whether we should timeout Udp connections");
AZ_CVAR(AZ::TimeMs, net_UdpPacketTimeSliceMs, AZ::TimeMs{ 8 }, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The number of milliseconds to allow for packet processing");
AZ_CVAR(AZ::TimeMs, net_UdpHeartbeatTimeMs, AZ::TimeMs{ 2 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Udp connection heartbeat frequency");
AZ_CVAR(uint32_t, net_UdpUnackedHeartbeats, 5, nullptr, AZ::ConsoleFunctorFlags::Null, "The number of heartbeats to attempt to send to keep a connection alive before giving up");
AZ_CVAR(AZ::TimeMs, net_UdpDefaultTimeoutMs, AZ::TimeMs{ 10 * 1000 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Time in milliseconds before we timeout an idle Udp connection");
AZ_CVAR(AZ::TimeMs, net_MinPacketTimeoutMs, AZ::TimeMs{ 200 }, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Minimum time to wait before timing out an unacked packet");
AZ_CVAR(int32_t, net_MaxTimeoutsPerFrame, 1000, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Maximum number of packet timeouts to allow to process in a single frame");
@@ -139,7 +139,8 @@ namespace AzNetworking
}
const ConnectionId connectionId = m_connectionSet.GetNextConnectionId();
const TimeoutId timeoutId = m_connectionTimeoutQueue.RegisterItem(aznumeric_cast<uint64_t>(connectionId), m_timeoutMs);
const AZ::TimeMs timeoutTimeMs = m_timeoutMs / static_cast<AZ::TimeMs>(static_cast<int32_t>(net_UdpUnackedHeartbeats));
const TimeoutId timeoutId = m_connectionTimeoutQueue.RegisterItem(aznumeric_cast<uint64_t>(connectionId), timeoutTimeMs);
AZStd::unique_ptr<UdpConnection> connection = AZStd::make_unique<UdpConnection>(connectionId, remoteAddress, *this, ConnectionRole::Connector);
UdpPacketEncodingBuffer dtlsData;
@@ -277,6 +278,7 @@ namespace AzNetworking
}
timeoutItem->UpdateTimeoutTime(startTimeMs);
connection->m_timeoutCounter = 0;
PacketDispatchResult handledPacket = PacketDispatchResult::Failure;
if (header.GetPacketType() < aznumeric_cast<PacketType>(CorePackets::PacketType::MAX))
@@ -319,16 +321,10 @@ namespace AzNetworking
const AZ::TimeMs receiveTimeMs = AZ::GetElapsedTimeMs() - startTimeMs;
// Time out any stale client connections
{
ConnectionTimeoutFunctor functor(*this);
m_connectionTimeoutQueue.UpdateTimeouts(functor);
}
m_connectionTimeoutQueue.UpdateTimeouts([this](TimeoutQueue::TimeoutItem& item) { return HandleConnectionTimeout(item); });
// Time out any packets that haven't been acked within our timeout window
{
PacketTimeoutFunctor functor(*this);
m_packetTimeoutQueue.UpdateTimeouts(functor, static_cast<int32_t>(net_MaxTimeoutsPerFrame));
}
m_packetTimeoutQueue.UpdateTimeouts([this](TimeoutQueue::TimeoutItem& item) { return HandlePacketTimeout(item); }, static_cast<int32_t>(net_MaxTimeoutsPerFrame));
// Delete any connections we've disconnected
for (RemovedConnection& removedConnection : m_removedConnections)
@@ -709,21 +705,14 @@ namespace AzNetworking
{
// Packets involved in handshake are InitiateConnection, ConnectionHandshake and FragmentedPackets of ConnectionHandshake
return packetType == aznumeric_cast<PacketType>(CorePackets::PacketType::InitiateConnectionPacket) ||
packetType == aznumeric_cast<PacketType>(CorePackets::PacketType::ConnectionHandshakePacket) ||
(packetType == aznumeric_cast<PacketType>(CorePackets::PacketType::FragmentedPacket) && endpoint.IsConnecting());
packetType == aznumeric_cast<PacketType>(CorePackets::PacketType::ConnectionHandshakePacket) ||
(packetType == aznumeric_cast<PacketType>(CorePackets::PacketType::FragmentedPacket) && endpoint.IsConnecting());
}
UdpNetworkInterface::ConnectionTimeoutFunctor::ConnectionTimeoutFunctor(UdpNetworkInterface& networkInterface)
: m_networkInterface(networkInterface)
{
;
}
TimeoutResult UdpNetworkInterface::ConnectionTimeoutFunctor::HandleTimeout(TimeoutQueue::TimeoutItem& item)
TimeoutResult UdpNetworkInterface::HandleConnectionTimeout(TimeoutQueue::TimeoutItem& item)
{
const ConnectionId connectionId = ConnectionId(aznumeric_cast<uint32_t>(item.m_userData));
UdpConnection* udpConnection = static_cast<UdpConnection*>(m_networkInterface.m_connectionSet.GetConnection(connectionId));
UdpConnection* udpConnection = static_cast<UdpConnection*>(m_connectionSet.GetConnection(connectionId));
if (udpConnection == nullptr)
{
@@ -731,22 +720,23 @@ namespace AzNetworking
return TimeoutResult::Delete;
}
if (udpConnection->GetConnectionState() == ConnectionState::Connecting)
if ((udpConnection->GetConnectionState() == ConnectionState::Connecting)
&& udpConnection->GetDtlsEndpoint().IsConnecting())
{
if (udpConnection->GetDtlsEndpoint().IsConnecting())
{
// DTLS prefers we resend data lost over the wire with fresh SSL IDs so account for that here
UdpPacketEncodingBuffer dtlsData;
udpConnection->ProcessHandshakeData(dtlsData);
return TimeoutResult::Refresh;
}
// DTLS prefers we resend data lost over the wire with fresh SSL IDs so account for that here
UdpPacketEncodingBuffer dtlsData;
udpConnection->ProcessHandshakeData(dtlsData);
return TimeoutResult::Refresh;
}
if (udpConnection->GetConnectionRole() == ConnectionRole::Connector)
if ((udpConnection->GetConnectionRole() == ConnectionRole::Connector)
&& (udpConnection->m_timeoutCounter < net_UdpUnackedHeartbeats))
{
udpConnection->SendUnreliablePacket(CorePackets::HeartbeatPacket());
// Set the request response flag to true since we want a response to keep the connection alive
udpConnection->SendUnreliablePacket(CorePackets::HeartbeatPacket(true));
++udpConnection->m_timeoutCounter;
}
else if (net_UdpTimeoutConnections && (m_networkInterface.GetTimeoutMs() > AZ::TimeMs{ 0 }))
else if (net_UdpTimeoutConnections && (GetTimeoutMs() > AZ::TimeMs{ 0 }))
{
udpConnection->Disconnect(DisconnectReason::Timeout, TerminationEndpoint::Local);
return TimeoutResult::Delete;
@@ -755,19 +745,13 @@ namespace AzNetworking
return TimeoutResult::Refresh;
}
UdpNetworkInterface::PacketTimeoutFunctor::PacketTimeoutFunctor(UdpNetworkInterface& networkInterface)
: m_networkInterface(networkInterface)
{
;
}
TimeoutResult UdpNetworkInterface::PacketTimeoutFunctor::HandleTimeout(TimeoutQueue::TimeoutItem& item)
TimeoutResult UdpNetworkInterface::HandlePacketTimeout(TimeoutQueue::TimeoutItem& item)
{
ConnectionId connectionId;
PacketId packetId;
ReliabilityType reliability;
DecodeTimeoutId(item.m_userData, connectionId, packetId, reliability);
UdpConnection* connection = static_cast<UdpConnection*>(m_networkInterface.m_connectionSet.GetConnection(connectionId));
UdpConnection* connection = static_cast<UdpConnection*>(m_connectionSet.GetConnection(connectionId));
if (connection == nullptr)
{
@@ -782,16 +766,14 @@ namespace AzNetworking
case PacketTimeoutResult::Acked:
// Packet was already acked, just discard this timeout entry
return TimeoutResult::Delete;
case PacketTimeoutResult::Pending:
// Packet timed out before we received any info about it's sequence from the remote endpoint
// The connection latency may have increased, and our Rtt metrics may still be adjusting..
// Just throw it back into the timeout queue
return TimeoutResult::Refresh;
case PacketTimeoutResult::Lost:
// Packet timed out and was not acked, so we consider it lost
m_networkInterface.m_connectionListener.OnPacketLost(connection, packetId);
m_connectionListener.OnPacketLost(connection, packetId);
break;
}
@@ -149,34 +149,24 @@ namespace AzNetworking
//! @param endpoint whether the disconnection was initiated locally or remotely
void RequestDisconnect(UdpConnection* connection, DisconnectReason reason, TerminationEndpoint endpoint);
//! Internal helper to check if a packet's type is for connection handshake
//! Internal helper to check if a packet's type is for connection handshake.
//! @param endpoint DTLS endpoint participating in the handshake
//! @param packetType type of the packet
//! @return if the packet is for handshake
bool IsHandshakePacket(const DtlsEndpoint& endpoint, AzNetworking::PacketType packetType) const;
//! Internal helper to manage connection timeout behaviour.
//! @param item the timeout item corresponding to the timed out connection
//! @return whether to delete or persist the timeout item
TimeoutResult HandleConnectionTimeout(TimeoutQueue::TimeoutItem& item);
//! Internal helper to manage packet timeout behaviour.
//! @param item the timeout item corresponding to the timed out packet
//! @return whether to delete or persist the timeout item
TimeoutResult HandlePacketTimeout(TimeoutQueue::TimeoutItem& item);
AZ_DISABLE_COPY_MOVE(UdpNetworkInterface);
struct ConnectionTimeoutFunctor final
: public ITimeoutHandler
{
ConnectionTimeoutFunctor(UdpNetworkInterface& networkInterface);
TimeoutResult HandleTimeout(TimeoutQueue::TimeoutItem& item) override;
private:
AZ_DISABLE_COPY_MOVE(ConnectionTimeoutFunctor);
UdpNetworkInterface& m_networkInterface;
};
struct PacketTimeoutFunctor final
: public ITimeoutHandler
{
PacketTimeoutFunctor(UdpNetworkInterface& networkInterface);
TimeoutResult HandleTimeout(TimeoutQueue::TimeoutItem& item) override;
private:
AZ_DISABLE_COPY_MOVE(PacketTimeoutFunctor);
UdpNetworkInterface& m_networkInterface;
};
AZ::Name m_name;
TrustZone m_trustZone;
uint16_t m_port = 0;
@@ -10,7 +10,6 @@ AzToolsFramework--EntityOutlinerWidget #m_display_options
{
qproperty-icon: url(:/stylesheet/img/UI20/menu-centered.svg);
qproperty-iconSize: 16px 16px;
qproperty-flat: true;
}
AzToolsFramework--EntityOutlinerWidget QTreeView
-337
View File
@@ -96,47 +96,6 @@ unsigned countElements (const std::vector<T>& arrT, const T& x)
*/
namespace stl
{
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compare member of class/struct.
//
// e.g. Sort Vec3s by x component
//
// std::sort(vec3s.begin(), vec3s.end(), stl::member_compare<Vec3, float, &Vec3::x>());
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename OWNER_TYPE, typename MEMBER_TYPE, MEMBER_TYPE OWNER_TYPE::* MEMBER_PTR, typename EQUALITY = std::less<MEMBER_TYPE> >
struct member_compare
{
inline bool operator () (const OWNER_TYPE& lhs, const OWNER_TYPE& rhs) const
{
return EQUALITY()(lhs.*MEMBER_PTR, rhs.*MEMBER_PTR);
}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Compare member of class/struct against parameter.
//
// e.g. Find Vec3 with x component less than 1.0
//
// std::find_if(vec3s.begin(), vec3s.end(), stl::member_compare_param<Vec3, float, &Vec3::x>(1.0f));
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template <typename OWNER_TYPE, typename MEMBER_TYPE, MEMBER_TYPE OWNER_TYPE::* MEMBER_PTR, typename EQUALITY = std::less<MEMBER_TYPE> >
struct member_compare_param
{
inline member_compare_param(const MEMBER_TYPE& _value)
: value(_value)
{
}
inline bool operator () (const OWNER_TYPE& rhs) const
{
return EQUALITY()(rhs.*MEMBER_PTR, value);
}
const MEMBER_TYPE& value;
};
//////////////////////////////////////////////////////////////////////////
//! Searches the given entry in the map by key, and if there is none, returns the default value
//////////////////////////////////////////////////////////////////////////
@@ -154,48 +113,6 @@ namespace stl
}
}
//////////////////////////////////////////////////////////////////////////
//! Inserts and returns a reference to the given value in the map, or returns the current one if it's already there.
//////////////////////////////////////////////////////////////////////////
template <typename Map>
inline typename Map::mapped_type& map_insert_or_get(Map& mapKeyToValue, const typename Map::key_type& key, const typename Map::mapped_type& defValue = typename Map::mapped_type())
{
auto&& iresult = mapKeyToValue.insert(typename Map::value_type(key, defValue));
return iresult.first->second;
}
// searches the given entry in the map by key, and if there is none, returns the default value
// The values are taken/returned in REFERENCEs rather than values
template <typename Key, typename mapped_type, typename Traits, typename Allocator>
inline mapped_type& find_in_map_ref(std::map<Key, mapped_type, Traits, Allocator>& mapKeyToValue, const Key& key, mapped_type& valueDefault)
{
typedef std::map<Key, mapped_type, Traits, Allocator> Map;
typename Map::iterator it = mapKeyToValue.find (key);
if (it == mapKeyToValue.end())
{
return valueDefault;
}
else
{
return it->second;
}
}
template <typename Key, typename mapped_type, typename Traits, typename Allocator>
inline const mapped_type& find_in_map_ref(const std::map<Key, mapped_type, Traits, Allocator>& mapKeyToValue, const Key& key, const mapped_type& valueDefault)
{
typedef std::map<Key, mapped_type, Traits, Allocator> Map;
typename Map::const_iterator it = mapKeyToValue.find (key);
if (it == mapKeyToValue.end())
{
return valueDefault;
}
else
{
return it->second;
}
}
//////////////////////////////////////////////////////////////////////////
//! Fills vector with contents of map.
//////////////////////////////////////////////////////////////////////////
@@ -210,20 +127,6 @@ namespace stl
}
}
//////////////////////////////////////////////////////////////////////////
//! Fills vector with contents of set.
//////////////////////////////////////////////////////////////////////////
template <class Set, class Vector>
inline void set_to_vector(const Set& theSet, Vector& array)
{
array.resize(0);
array.reserve(theSet.size());
for (typename Set::const_iterator it = theSet.begin(); it != theSet.end(); ++it)
{
array.push_back(*it);
}
}
//////////////////////////////////////////////////////////////////////////
//! Find and erase element from container.
// @return true if item was find and erased, false if item not found.
@@ -312,48 +215,6 @@ namespace stl
return false;
}
//////////////////////////////////////////////////////////////////////////
//! Push back to container unique element.
// @return true if item added, false overwise.
template <class CONTAINER, class PREDICATE, typename VALUE>
inline bool push_back_unique_if(CONTAINER& container, const PREDICATE& predicate, const VALUE& value)
{
typename CONTAINER::iterator end = container.end();
if (AZStd::find_if(container.begin(), end, predicate) == end)
{
container.push_back(value);
return true;
}
else
{
return false;
}
}
//////////////////////////////////////////////////////////////////////////
//! Push back to container contents of another container
template <class Container, class Iter>
inline void push_back_range(Container& container, Iter begin, Iter end)
{
for (Iter it = begin; it != end; ++it)
{
container.push_back(*it);
}
}
//////////////////////////////////////////////////////////////////////////
//! Push back to container contents of another container, if not already present
template <class Container, class Iter>
inline void push_back_range_unique(Container& container, Iter begin, Iter end)
{
for (Iter it = begin; it != end; ++it)
{
push_back_unique(container, *it);
}
}
//////////////////////////////////////////////////////////////////////////
//! Find element in container.
// @return true if item found.
@@ -373,107 +234,6 @@ namespace stl
return (it == last || value != *it) ? last : it;
}
//////////////////////////////////////////////////////////////////////////
//! Find element in a sorted container using binary search with logarithmic efficiency.
// @return true if item was inserted.
template <class Container, class Value>
inline bool binary_insert_unique(Container& container, const Value& value)
{
typename Container::iterator it = std::lower_bound(container.begin(), container.end(), value);
if (it != container.end())
{
if (*it == value)
{
return false;
}
container.insert(it, value);
}
else
{
container.insert(container.end(), value);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
//! Find element in a sorted container using binary search with logarithmic efficiency.
// and erases if element found.
// @return true if item was erased.
template <class Container, class Value>
inline bool binary_erase(Container& container, const Value& value)
{
typename Container::iterator it = std::lower_bound(container.begin(), container.end(), value);
if (it != container.end() && *it == value)
{
container.erase(it);
return true;
}
return false;
}
template <typename ItT, typename Func>
ItT remove_from_heap(ItT begin, ItT end, ItT at, Func order)
{
using std::swap;
--end;
if (at == end)
{
return at;
}
size_t idx = std::distance(begin, at);
swap(*end, *at);
size_t length = std::distance(begin, end);
size_t parent, child;
if (idx > 0 && order(*(begin + idx / 2), *(begin + idx)))
{
do
{
parent = idx / 2;
swap(*(begin + idx), *(begin + parent));
idx = parent;
if (idx == 0 || order(*(begin + idx), *(begin + idx / 2)))
{
return end;
}
}
while (true);
}
else
{
do
{
child = idx * 2 + 1;
if (child >= length)
{
return end;
}
ItT left = begin + child;
ItT right = begin + child + 1;
if (right < end && order(*left, *right))
{
++child;
}
if (order(*(begin + child), *(begin + idx)))
{
return end;
}
swap(*(begin + child), *(begin + idx));
idx = child;
}
while (true);
}
return end;
}
struct container_object_deleter
{
template<typename T>
@@ -506,18 +266,6 @@ namespace stl
return type.c_str();
}
//////////////////////////////////////////////////////////////////////////
//! Case sensetive less key for any type convertable to const char*.
//////////////////////////////////////////////////////////////////////////
template <class Type>
struct less_strcmp
{
bool operator()(const Type& left, const Type& right) const
{
return strcmp(constchar_cast(left), constchar_cast(right)) < 0;
}
};
//////////////////////////////////////////////////////////////////////////
//! Case insensetive less key for any type convertable to const char*.
template <class Type>
@@ -690,89 +438,4 @@ namespace stl
stl::free_container(container);
}
};
template <typename T, size_t Length, typename Func>
inline void for_each_array(T (&buffer)[Length], Func func)
{
std::for_each(&buffer[0], &buffer[Length], func);
}
template <typename T, typename D, size_t Length, typename Func>
inline void for_each_array(StaticInstance<T, D>(&buffer)[Length], Func func)
{
for (size_t idx = 0; idx < Length; ++idx)
{
func(*buffer[idx]);
}
}
template <typename T>
inline void destruct(T* p)
{
p->~T();
}
}
#define DEFINE_INTRUSIVE_LINKED_LIST(Class) \
template<> \
Class * stl::intrusive_linked_list_node<Class>::m_root_intrusive = nullptr;
// define the maplikestruct, used to approximate the memory requirements for a map node
namespace stl
{
struct MapLikeStruct
{
bool color;
void* parent;
void* left;
void* right;
};
}
template <class Map>
unsigned sizeOfMap(Map& map)
{
unsigned size = 0;
for (typename Map::iterator it = map.begin(); it != map.end(); it++)
{
typename Map::mapped_type& T = it->second;
size += T.Size();
}
size += map.size() * sizeof(stl::MapLikeStruct);
return size;
}
template <class Map>
unsigned sizeOfMapStr(Map& map)
{
unsigned size = 0;
for (typename Map::iterator it = map.begin(); it != map.end(); it++)
{
typename Map::mapped_type& T = it->second;
size += T.capacity();
}
size += map.size() * sizeof(stl::MapLikeStruct);
return size;
}
template <class Map>
unsigned sizeOfMapP(Map& map)
{
unsigned size = 0;
for (typename Map::iterator it = map.begin(); it != map.end(); it++)
{
typename Map::mapped_type& T = it->second;
size += T->Size();
}
size += map.size() * sizeof(stl::MapLikeStruct);
return size;
}
template <class Map>
unsigned sizeOfMapS(Map& map)
{
unsigned size = 0;
for (typename Map::iterator it = map.begin(); it != map.end(); it++)
{
typename Map::mapped_type& T = it->second;
size += sizeof(T);
}
size += map.size() * sizeof(stl::MapLikeStruct);
return size;
}
-2
View File
@@ -509,8 +509,6 @@ void CSystem::ShutDown()
ShutdownFileSystem();
ShutdownModuleLibraries();
EBUS_EVENT(CrySystemEventBus, OnCrySystemPostShutdown);
}
-12
View File
@@ -303,8 +303,6 @@ public:
void SetVersionInfo(const char* const szVersion);
#endif
void ShutdownModuleLibraries();
#if defined(WIN32)
friend LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif
@@ -323,8 +321,6 @@ private:
// Release all resources.
void ShutDown();
bool LoadEngineDLLs();
//! @name Initialization routines
//@{
bool InitConsole();
@@ -340,11 +336,8 @@ private:
void CreateSystemVars();
void CreateAudioVars();
AZStd::unique_ptr<AZ::DynamicModuleHandle> LoadDLL(const char* dllName);
void FreeLib(AZStd::unique_ptr<AZ::DynamicModuleHandle>& hLibModule);
bool UnloadDLL(const char* dllName);
void QueryVersionInfo();
void LogVersion();
void LogBuildInfo();
@@ -359,8 +352,6 @@ private:
void AddCVarGroupDirectory(const AZStd::string& sPath) override;
AZStd::unique_ptr<AZ::DynamicModuleHandle> LoadDynamiclibrary(const char* dllName) const;
#if defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEM_H_SECTION_3
#include AZ_RESTRICTED_FILE(System_h)
@@ -416,9 +407,6 @@ private: // ------------------------------------------------------
bool m_bDrawConsole; //!< Set to true if OK to draw the console.
bool m_bDrawUI; //!< Set to true if OK to draw UI.
std::map<AZ::Crc32, AZStd::unique_ptr<AZ::DynamicModuleHandle> > m_moduleDLLHandles;
//! current active process
IProcess* m_pProcess;
-207
View File
@@ -12,7 +12,6 @@
#if defined(AZ_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
#undef AZ_RESTRICTED_SECTION
#define SYSTEMINIT_CPP_SECTION_1 1
#define SYSTEMINIT_CPP_SECTION_2 2
#define SYSTEMINIT_CPP_SECTION_3 3
#define SYSTEMINIT_CPP_SECTION_4 4
@@ -168,30 +167,6 @@ void CryEngineSignalHandler(int signal)
#define LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME "Libs/Localization/localization.xml"
//////////////////////////////////////////////////////////////////////////
#if defined(WIN32) || defined(LINUX) || defined(APPLE)
# define DLL_INITFUNC_RENDERER "PackageRenderConstructor"
# define DLL_INITFUNC_SOUND "CreateSoundSystem"
# define DLL_INITFUNC_FONT "CreateCryFontInterface"
# define DLL_INITFUNC_3DENGINE "CreateCry3DEngine"
# define DLL_INITFUNC_UI "CreateLyShineInterface"
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
#elif defined(AZ_RESTRICTED_PLATFORM)
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_1
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
#endif
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
#else
# define DLL_INITFUNC_RENDERER (LPCSTR)1
# define DLL_INITFUNC_RENDERER (LPCSTR)1
# define DLL_INITFUNC_SOUND (LPCSTR)1
# define DLL_INITFUNC_PHYSIC (LPCSTR)1
# define DLL_INITFUNC_FONT (LPCSTR)1
# define DLL_INITFUNC_3DENGINE (LPCSTR)1
# define DLL_INITFUNC_UI (LPCSTR)1
#endif
#define AZ_TRACE_SYSTEM_WINDOW AZ::Debug::Trace::GetDefaultSystemWindow()
#ifdef WIN32
@@ -285,96 +260,6 @@ static void CmdCrashTest(IConsoleCmdArgs* pArgs)
}
AZ_POP_DISABLE_WARNING
//////////////////////////////////////////////////////////////////////////
struct SysSpecOverrideSink
: public ILoadConfigurationEntrySink
{
virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup)
{
ICVar* pCvar = gEnv->pConsole->GetCVar(szKey);
if (pCvar)
{
const bool wasNotInConfig = ((pCvar->GetFlags() & VF_WASINCONFIG) == 0);
bool applyCvar = wasNotInConfig;
if (applyCvar == false)
{
// Special handling for sys_spec_full
if (azstricmp(szKey, "sys_spec_full") == 0)
{
// If it is set to 0 then ignore this request to set to something else
// If it is set to 0 then the user wants to changes system spec settings in system.cfg
if (pCvar->GetIVal() != 0)
{
applyCvar = true;
}
}
else
{
// This could bypass the restricted cvar checks that exist elsewhere depending on
// the calling code so we also need check here before setting.
bool isConst = pCvar->IsConstCVar();
bool isCheat = ((pCvar->GetFlags() & (VF_CHEAT | VF_CHEAT_NOCHECK | VF_CHEAT_ALWAYS_CHECK)) != 0);
bool isReadOnly = ((pCvar->GetFlags() & VF_READONLY) != 0);
bool isDeprecated = ((pCvar->GetFlags() & VF_DEPRECATED) != 0);
bool allowApplyCvar = true;
if ((isConst || isCheat || isReadOnly) || isDeprecated)
{
allowApplyCvar = !isDeprecated && (gEnv->pSystem->IsDevMode()) || (gEnv->IsEditor());
}
if ((allowApplyCvar) || ALLOW_CONST_CVAR_MODIFICATIONS)
{
applyCvar = true;
}
}
}
if (applyCvar)
{
pCvar->Set(szValue);
}
else
{
CryLogAlways("NOT VF_WASINCONFIG Ignoring cvar '%s' new value '%s' old value '%s' group '%s'", szKey, szValue, pCvar->GetString(), szGroup);
}
}
else
{
CryLogAlways("Can't find cvar '%s' value '%s' group '%s'", szKey, szValue, szGroup);
}
}
};
#if !defined(CONSOLE)
struct SysSpecOverrideSinkConsole
: public ILoadConfigurationEntrySink
{
virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, const char* szGroup)
{
// Ignore platform-specific cvars that should just be executed on the console
if (azstricmp(szGroup, "Platform") == 0)
{
return;
}
ICVar* pCvar = gEnv->pConsole->GetCVar(szKey);
if (pCvar)
{
pCvar->Set(szValue);
}
else
{
// If the cvar doesn't exist, calling this function only saves the value in case it's registered later where
// at that point it will be set from the stored value. This is required because otherwise registering the
// cvar bypasses any callbacks and uses values directly from the cvar group files.
gEnv->pConsole->LoadConfigVar(szKey, szValue);
}
}
};
#endif
static ESystemConfigPlatform GetDevicePlatform()
{
#if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX)
@@ -398,98 +283,6 @@ static ESystemConfigPlatform GetDevicePlatform()
#endif
}
//////////////////////////////////////////////////////////////////////////
#if !defined(AZ_MONOLITHIC_BUILD)
AZStd::unique_ptr<AZ::DynamicModuleHandle> CSystem::LoadDynamiclibrary(const char* dllName) const
{
AZStd::unique_ptr<AZ::DynamicModuleHandle> handle = AZ::DynamicModuleHandle::Create(dllName);
bool libraryLoaded = handle->Load(false);
// We need to inject the environment first thing so that allocators are available immediately
InjectEnvironmentFunction injectEnv = handle->GetFunction<InjectEnvironmentFunction>(INJECT_ENVIRONMENT_FUNCTION);
if (injectEnv)
{
auto env = AZ::Environment::GetInstance();
injectEnv(env);
}
if (!libraryLoaded)
{
handle.release();
}
return handle;
}
//////////////////////////////////////////////////////////////////////////
AZStd::unique_ptr<AZ::DynamicModuleHandle> CSystem::LoadDLL(const char* dllName)
{
AZ_TracePrintf(AZ_TRACE_SYSTEM_WINDOW, "Loading DLL: %s", dllName);
AZStd::unique_ptr<AZ::DynamicModuleHandle> handle = LoadDynamiclibrary(dllName);
if (!handle)
{
#if defined(LINUX) || defined(APPLE)
AZ_Assert(false, "Error loading dylib: %s, error : %s\n", dllName, dlerror());
#else
AZ_Assert(false, "Error loading dll: %s, error code %d", dllName, GetLastError());
#endif
return handle;
}
return handle;
}
// TODO:DLL #endif //#if defined(AZ_HAS_DLL_SUPPORT) && !defined(AZ_MONOLITHIC_BUILD)
#endif //if !defined(AZ_MONOLITHIC_BUILD)
//////////////////////////////////////////////////////////////////////////
bool CSystem::LoadEngineDLLs()
{
return true;
}
//////////////////////////////////////////////////////////////////////////
bool CSystem::UnloadDLL(const char* dllName)
{
bool isSuccess = false;
AZ::Crc32 key(dllName);
AZStd::unique_ptr<AZ::DynamicModuleHandle> empty;
AZStd::unique_ptr<AZ::DynamicModuleHandle>& hModule = stl::find_in_map_ref(m_moduleDLLHandles, key, empty);
if ((hModule) && (hModule->IsLoaded()))
{
DetachEnvironmentFunction detachEnv = hModule->GetFunction<DetachEnvironmentFunction>(DETACH_ENVIRONMENT_FUNCTION);
if (detachEnv)
{
detachEnv();
}
isSuccess = hModule->Unload();
hModule.release();
}
return isSuccess;
}
//////////////////////////////////////////////////////////////////////////
void CSystem::ShutdownModuleLibraries()
{
#if !defined(AZ_MONOLITHIC_BUILD)
for (auto iterator = m_moduleDLLHandles.begin(); iterator != m_moduleDLLHandles.end(); ++iterator)
{
if (iterator->second->IsLoaded())
{
iterator->second->Unload();
}
iterator->second.release();
}
m_moduleDLLHandles.clear();
#endif // !defined(AZ_MONOLITHIC_BUILD)
}
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
bool CSystem::InitConsole()
@@ -49,6 +49,12 @@ int main(int argc, char* argv[])
AZStd::unique_ptr<AzFramework::ProcessWatcher> shellProcess(AzFramework::ProcessWatcher::LaunchProcess(shellProcessLaunch, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE));
shellProcess->WaitForProcessToExit(120);
shellProcess.reset();
parameters = AZStd::string::format("-c \"%s/scripts/o3de.sh register --this-engine\"", enginePath.c_str());
shellProcessLaunch.m_commandlineParameters = parameters;
shellProcess.reset(AzFramework::ProcessWatcher::LaunchProcess(shellProcessLaunch, AzFramework::ProcessCommunicationType::COMMUNICATOR_TYPE_NONE));
shellProcess->WaitForProcessToExit(120);
shellProcess.reset();
AZ::IO::FixedMaxPath projectManagerPath = installedBinariesFolder/"o3de.app"/"Contents"/"MacOS"/"o3de";
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;
@@ -10,6 +10,8 @@
#include <QProcessEnvironment>
#include <QDir>
#include <AzCore/Utils/Utils.h>
namespace O3DE::ProjectManager
{
namespace ProjectUtils
@@ -94,5 +96,10 @@ namespace O3DE::ProjectManager
QProcessEnvironment::systemEnvironment(),
QObject::tr("Running get_python script..."));
}
AZ::IO::FixedMaxPath GetEditorDirectory()
{
return AZ::Utils::GetExecutableDirectory();
}
} // namespace ProjectUtils
} // namespace O3DE::ProjectManager
@@ -11,6 +11,9 @@
#include <QStandardPaths>
#include <QDir>
#include <AzCore/Utils/Utils.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
namespace O3DE::ProjectManager
{
namespace ProjectUtils
@@ -104,5 +107,35 @@ namespace O3DE::ProjectManager
QProcessEnvironment::systemEnvironment(),
QObject::tr("Running get_python script..."));
}
AZ::IO::FixedMaxPath GetEditorDirectory()
{
AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory();
AZ::IO::FixedMaxPath editorPath{ executableDirectory };
editorPath /= "../../../Editor.app/Contents/MacOS";
editorPath = editorPath.LexicallyNormal();
if (!AZ::IO::SystemFile::IsDirectory(editorPath.c_str()))
{
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
{
if (AZ::IO::FixedMaxPath installedBinariesPath;
settingsRegistry->Get(installedBinariesPath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_InstalledBinaryFolder))
{
if (AZ::IO::FixedMaxPath engineRootFolder;
settingsRegistry->Get(engineRootFolder.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder))
{
editorPath = engineRootFolder / installedBinariesPath / "Editor.app/Contents/MacOS";
}
}
}
if (!AZ::IO::SystemFile::IsDirectory(editorPath.c_str()))
{
AZ_Error("ProjectManager", false, "Unable to find the Editor app bundle!");
}
}
return editorPath;
}
} // namespace ProjectUtils
} // namespace O3DE::ProjectManager
@@ -14,6 +14,8 @@
#include <QProcess>
#include <QProcessEnvironment>
#include <AzCore/Utils/Utils.h>
namespace O3DE::ProjectManager
{
namespace ProjectUtils
@@ -139,5 +141,10 @@ namespace O3DE::ProjectManager
QProcessEnvironment::systemEnvironment(),
QObject::tr("Running get_python script..."));
}
AZ::IO::FixedMaxPath GetEditorDirectory()
{
return AZ::Utils::GetExecutableDirectory();
}
} // namespace ProjectUtils
} // namespace O3DE::ProjectManager
@@ -14,6 +14,7 @@
#include <QWidget>
#include <QProcessEnvironment>
#include <AzCore/IO/Path/Path_fwd.h>
#include <AzCore/Outcome/Outcome.h>
namespace O3DE::ProjectManager
@@ -67,7 +68,8 @@ namespace O3DE::ProjectManager
AZ::Outcome<QString, QString> GetProjectBuildPath(const QString& projectPath);
AZ::Outcome<void, QString> OpenCMakeGUI(const QString& projectPath);
AZ::Outcome<QString, QString> RunGetPythonScript(const QString& enginePath);
AZ::IO::FixedMaxPath GetEditorDirectory();
} // namespace ProjectUtils
} // namespace O3DE::ProjectManager
@@ -392,11 +392,11 @@ namespace O3DE::ProjectManager
{
if (!WarnIfInBuildQueue(projectPath))
{
AZ::IO::FixedMaxPath executableDirectory = AZ::Utils::GetExecutableDirectory();
AZ::IO::FixedMaxPath executableDirectory = ProjectUtils::GetEditorDirectory();
AZStd::string executableFilename = "Editor";
AZ::IO::FixedMaxPath editorExecutablePath = executableDirectory / (executableFilename + AZ_TRAIT_OS_EXECUTABLE_EXTENSION);
auto cmdPath = AZ::IO::FixedMaxPathString::format(
"%s -regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(),
"%s --regset=\"/Amazon/AzCore/Bootstrap/project_path=%s\"", editorExecutablePath.c_str(),
projectPath.toStdString().c_str());
AzFramework::ProcessLauncher::ProcessLaunchInfo processLaunchInfo;