Переглянути джерело

Add SystemTick Network Interfaces and address SystemTick failing to occur in background

Signed-off-by: puvvadar <[email protected]>
puvvadar 3 роки тому
батько
коміт
177569a525

+ 8 - 7
Code/Editor/CryEdit.cpp

@@ -2274,19 +2274,20 @@ int CCryEditApp::IdleProcessing(bool bBackgroundUpdate)
 
             GetIEditor()->Notify(eNotify_OnIdleUpdate);
         }
-
-        AZ::ComponentApplication* componentApplication = nullptr;
-        AZ::ComponentApplicationBus::BroadcastResult(componentApplication, &AZ::ComponentApplicationRequests::GetApplication);
-        if (componentApplication)
-        {
-            componentApplication->TickSystem();
-        }
     }
     else if (GetIEditor()->GetSystem() && GetIEditor()->GetSystem()->GetILog())
     {
         GetIEditor()->GetSystem()->GetILog()->Update(); // print messages from other threads
     }
 
+    // Tick System Events, even in the background
+    AZ::ComponentApplication* componentApplication = nullptr;
+    AZ::ComponentApplicationBus::BroadcastResult(componentApplication, &AZ::ComponentApplicationRequests::GetApplication);
+    if (componentApplication)
+    {
+        componentApplication->TickSystem();
+    }
+
     DisplayLevelLoadErrors();
 
     if (CConsoleSCB::GetCreatedInstance())

+ 19 - 22
Code/Framework/AzFramework/AzFramework/TargetManagement/TargetManagementComponent.cpp

@@ -211,7 +211,7 @@ namespace AzFramework
         td.m_cpuId = AFFINITY_MASK_USERTHREADS;
         m_threadHandle = AZStd::thread(td, AZStd::bind(&TargetManagementComponent::TickThread, this));
 
-        m_networkInterface = AZ::Interface<AzNetworking::INetworking>::Get()->CreateNetworkInterface(
+        m_networkInterface = AZ::Interface<AzNetworking::INetworking>::Get()->CreateSystemNetworkInterface(
             m_networkInterfaceName, AzNetworking::ProtocolType::Tcp, AzNetworking::TrustZone::ExternalClientToServer, *this);
         m_networkInterface->SetTimeoutMs(AZ::TimeMs(0));
         m_targetJoinThread = AZStd::make_unique<TargetJoinThread>(target_autoconnect_interval);
@@ -721,22 +721,21 @@ namespace AzFramework
 
     void connect_target([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
     {
-        for (auto& networkInterface : AZ::Interface<AzNetworking::INetworking>::Get()->GetNetworkInterfaces())
+        AzNetworking::INetworkInterface* networkInterface =
+            AZ::Interface<AzNetworking::INetworking>::Get()->RetrieveNetworkInterface(AZ::Name("TargetManagement"));
+        if (networkInterface)
         {
-            if (networkInterface.first == AZ::Name("TargetManagement"))
-            {
-                const uint16_t serverPort = target_port;
+            const uint16_t serverPort = target_port;
 
-                AzNetworking::ConnectionId connId = networkInterface.second->Connect(
-                    AzNetworking::IpAddress(TargetServerAddress, serverPort, AzNetworking::ProtocolType::Tcp));
-                if (connId != AzNetworking::InvalidConnectionId)
-                {
-                    AzFrameworkPackets::TargetConnect initPacket;
-                    initPacket.SetPersistentId(AZ::Crc32(Platform::GetPersistentName()));
-                    initPacket.SetCapabilities(Neighborhood::NEIGHBOR_CAP_LUA_VM | Neighborhood::NEIGHBOR_CAP_LUA_DEBUGGER);
-                    initPacket.SetDisplayName(Platform::GetPersistentName());
-                    networkInterface.second->SendReliablePacket(connId, initPacket);
-                }
+            AzNetworking::ConnectionId connId =
+                networkInterface->Connect(AzNetworking::IpAddress(TargetServerAddress, serverPort, AzNetworking::ProtocolType::Tcp));
+            if (connId != AzNetworking::InvalidConnectionId)
+            {
+                AzFrameworkPackets::TargetConnect initPacket;
+                initPacket.SetPersistentId(AZ::Crc32(Platform::GetPersistentName()));
+                initPacket.SetCapabilities(Neighborhood::NEIGHBOR_CAP_LUA_VM | Neighborhood::NEIGHBOR_CAP_LUA_DEBUGGER);
+                initPacket.SetDisplayName(Platform::GetPersistentName());
+                networkInterface->SendReliablePacket(connId, initPacket);
             }
         }
     }
@@ -757,14 +756,12 @@ namespace AzFramework
     void TargetJoinThread::OnUpdate([[maybe_unused]] AZ::TimeMs updateRateMs)
     {
         connect_target(AZ::ConsoleCommandContainer());
-        for (auto& networkInterface : AZ::Interface<AzNetworking::INetworking>::Get()->GetNetworkInterfaces())
+        AzNetworking::INetworkInterface* networkInterface =
+            AZ::Interface<AzNetworking::INetworking>::Get()->RetrieveNetworkInterface(AZ::Name("TargetManagement"));
+        if (networkInterface && networkInterface->GetConnectionSet().GetActiveConnectionCount() > 0)
         {
-            if (networkInterface.first == AZ::Name("TargetManagement") &&
-                networkInterface.second->GetConnectionSet().GetActiveConnectionCount() > 0)
-            {
-                Stop();
-                Join();
-            }
+            Stop();
+            Join();
         }
     }
 }   // namespace AzFramework

+ 14 - 0
Code/Framework/AzNetworking/AzNetworking/Framework/INetworking.h

@@ -46,6 +46,16 @@ namespace AzNetworking
         //! @return pointer to the instantiated network interface, or nullptr on error
         virtual INetworkInterface* CreateNetworkInterface(const AZ::Name& name, ProtocolType protocolType, TrustZone trustZone, IConnectionListener& listener) = 0;
 
+        //! Creates a new network interface instance with the provided parameters that operates on the SystemTickBus.
+        //! System Network Interfaces are suitable for cases where updates occur regardless of application state such as debug utilities.
+        //! Caller does not assume ownership, instance should be destroyed by calling DestroyNetworkInterface
+        //! @param name         the name to assign to this network interface
+        //! @param protocolType the type of interface to instantiate (Tcp or Udp)
+        //! @param trustZone    the trust level associated with this network interface (client to server or server to server)
+        //! @param listener     the connection listener responsible for handling connection events
+        //! @return pointer to the instantiated network interface, or nullptr on error
+        virtual INetworkInterface* CreateSystemNetworkInterface(const AZ::Name& name, ProtocolType protocolType, TrustZone trustZone, IConnectionListener& listener) = 0;
+
         //! Retrieves a network interface instance by name.
         //! @param name the name of the network interface to retrieve
         //! @return pointer to the requested network interface, or nullptr on error
@@ -74,6 +84,10 @@ namespace AzNetworking
         //! @return the raw network interfaces owned by the networking instance
         virtual const NetworkInterfaces& GetNetworkInterfaces() const = 0;
 
+        //! Returns the raw network interfaces on the SystemTickBus owned by the networking instance
+        //! @return the raw network interfaces on the SystemTickBus owned by the networking instance
+        virtual const NetworkInterfaces& GetSystemNetworkInterfaces() const = 0;
+
         //! Returns the number of sockets monitored by our TcpListenThread.
         //! @return the number of sockets monitored by our TcpListenThread
         virtual uint32_t GetTcpListenThreadSocketCount() const = 0;

+ 57 - 1
Code/Framework/AzNetworking/AzNetworking/Framework/NetworkingSystemComponent.cpp

@@ -50,6 +50,7 @@ namespace AzNetworking
     {
         // Delete all our network interfaces first so they can unregister from the reader and listen threads
         m_networkInterfaces.clear();
+        m_systemNetworkInterfaces.clear();
 
         m_compressorFactories.clear();
 
@@ -64,11 +65,13 @@ namespace AzNetworking
     void NetworkingSystemComponent::Activate()
     {
         AZ::TickBus::Handler::BusConnect();
+        AZ::SystemTickBus::Handler::BusConnect();
     }
 
     void NetworkingSystemComponent::Deactivate()
     {
         AZ::TickBus::Handler::BusDisconnect();
+        AZ::SystemTickBus::Handler::BusDisconnect();
     }
 
     void NetworkingSystemComponent::OnTick(float deltaTime, [[maybe_unused]] AZ::ScriptTimePoint time)
@@ -81,6 +84,16 @@ namespace AzNetworking
         }
     }
 
+    void NetworkingSystemComponent::OnSystemTick()
+    {
+        // Elapsed time is presently unused by NetworkInterfaces so pass 0
+        AZ::TimeMs elapsedMs = aznumeric_cast<AZ::TimeMs>(0);
+        for (auto& networkInterface : m_systemNetworkInterfaces)
+        {
+            networkInterface.second->Update(elapsedMs);
+        }
+    }
+
     int NetworkingSystemComponent::GetTickOrder()
     {
         return AZ::TICK_PLACEMENT;
@@ -108,6 +121,29 @@ namespace AzNetworking
         return returnResult;
     }
 
+    INetworkInterface* NetworkingSystemComponent::CreateSystemNetworkInterface(
+        const AZ::Name& name, ProtocolType protocolType, TrustZone trustZone, IConnectionListener& listener)
+    {
+        AZ_Assert(RetrieveNetworkInterface(name) == nullptr, "A network interface with this name already exists");
+
+        AZStd::unique_ptr<INetworkInterface> result = nullptr;
+        switch (protocolType)
+        {
+        case ProtocolType::Tcp:
+            result = AZStd::make_unique<TcpNetworkInterface>(name, listener, trustZone, *m_listenThread);
+            break;
+        case ProtocolType::Udp:
+            result = AZStd::make_unique<UdpNetworkInterface>(name, listener, trustZone, *m_readerThread);
+            break;
+        }
+        INetworkInterface* returnResult = result.get();
+        if (result != nullptr)
+        {
+            m_systemNetworkInterfaces.emplace(name, AZStd::move(result));
+        }
+        return returnResult;
+    }
+
     INetworkInterface* NetworkingSystemComponent::RetrieveNetworkInterface(const AZ::Name& name)
     {
         auto networkInterface = m_networkInterfaces.find(name);
@@ -115,12 +151,27 @@ namespace AzNetworking
         {
             return networkInterface->second.get();
         }
+        networkInterface = m_systemNetworkInterfaces.find(name);
+        if (networkInterface != m_systemNetworkInterfaces.end())
+        {
+            return networkInterface->second.get();
+        }
         return nullptr;
     }
 
     bool NetworkingSystemComponent::DestroyNetworkInterface(const AZ::Name& name)
     {
-        return m_networkInterfaces.erase(name) > 0;
+        if (m_networkInterfaces.erase(name) > 0)
+        {
+            return true;
+        }
+
+        if (m_systemNetworkInterfaces.erase(name) > 0)
+        {
+            return true;
+        }
+
+        return false;
     }
 
     void NetworkingSystemComponent::RegisterCompressorFactory(ICompressorFactory* factory)
@@ -153,6 +204,11 @@ namespace AzNetworking
         return m_networkInterfaces;
     }
 
+    const NetworkInterfaces& NetworkingSystemComponent::GetSystemNetworkInterfaces() const
+    {
+        return m_systemNetworkInterfaces;
+    }
+
     uint32_t NetworkingSystemComponent::GetTcpListenThreadSocketCount() const
     {
         return m_listenThread->GetSocketCount();

+ 9 - 0
Code/Framework/AzNetworking/AzNetworking/Framework/NetworkingSystemComponent.h

@@ -27,6 +27,7 @@ namespace AzNetworking
     class NetworkingSystemComponent final
         : public AZ::Component
         , public AZ::TickBus::Handler
+        , public AZ::SystemTickBus::Handler
         , public INetworking
     {
     public:
@@ -51,15 +52,22 @@ namespace AzNetworking
         int GetTickOrder() override;
         //! @}
 
+        //! AZ::TickBus::Handler overrides.
+        //! @{
+        void OnSystemTick() override;
+        //! @}
+
         //! INetworking overrides.
         //! @{
         INetworkInterface* CreateNetworkInterface(const AZ::Name& name, ProtocolType protocolType, TrustZone trustZone, IConnectionListener& listener) override;
+        INetworkInterface* CreateSystemNetworkInterface(const AZ::Name& name, ProtocolType protocolType, TrustZone trustZone, IConnectionListener& listener) override;
         INetworkInterface* RetrieveNetworkInterface(const AZ::Name& name) override;
         bool DestroyNetworkInterface(const AZ::Name& name) override;
         void RegisterCompressorFactory(ICompressorFactory* factory) override;
         AZStd::unique_ptr<ICompressor> CreateCompressor(const AZStd::string_view name) override;
         bool UnregisterCompressorFactory(const AZStd::string_view name) override;
         const NetworkInterfaces& GetNetworkInterfaces() const override;
+        const NetworkInterfaces& GetSystemNetworkInterfaces() const override;
         uint32_t GetTcpListenThreadSocketCount() const override;
         AZ::TimeMs GetTcpListenThreadUpdateTime() const override;
         uint32_t GetUdpReaderThreadSocketCount() const override;
@@ -76,6 +84,7 @@ namespace AzNetworking
         AZ_CONSOLEFUNC(NetworkingSystemComponent, DumpStats, AZ::ConsoleFunctorFlags::Null, "Dumps stats for all instantiated network interfaces");
 
         NetworkInterfaces m_networkInterfaces;
+        NetworkInterfaces m_systemNetworkInterfaces;
         AZStd::unique_ptr<TcpListenThread> m_listenThread;
         AZStd::unique_ptr<UdpReaderThread> m_readerThread;
 

+ 11 - 12
Code/Tools/LuaIDE/Source/StandaloneToolsApplication.cpp

@@ -104,21 +104,20 @@ namespace StandaloneTools
 
     bool BaseApplication::StartDebugService()
     {
-        for (auto& networkInterface : AZ::Interface<AzNetworking::INetworking>::Get()->GetNetworkInterfaces())
+        AzNetworking::INetworkInterface* networkInterface =
+            AZ::Interface<AzNetworking::INetworking>::Get()->RetrieveNetworkInterface(AZ::Name("TargetManagement"));
+        if (networkInterface)
         {
-            if (networkInterface.first == AZ::Name("TargetManagement"))
-            {
-                const auto console = AZ::Interface<AZ::IConsole>::Get();
-                uint16_t target_port = AzFramework::DefaultTargetPort;
-
-                if (console->GetCvarValue("target_port", target_port) != AZ::GetValueResult::Success)
-                {
-                    AZ_Assert(false, "TargetManagement port could not be found");
-                }
+            const auto console = AZ::Interface<AZ::IConsole>::Get();
+            uint16_t target_port = AzFramework::DefaultTargetPort;
 
-                networkInterface.second->Listen(target_port);
-                return true;
+            if (console->GetCvarValue("target_port", target_port) != AZ::GetValueResult::Success)
+            {
+                AZ_Assert(false, "TargetManagement port could not be found");
             }
+
+            networkInterface->Listen(target_port);
+            return true;
         }
         return false;
     }

+ 1 - 1
Gems/Multiplayer/Code/Source/Editor/MultiplayerEditorConnection.cpp

@@ -35,7 +35,7 @@ namespace Multiplayer
         : m_byteStream(&m_buffer)
     {
         const AZ::Name editorInterfaceName = AZ::Name(MpEditorInterfaceName);
-        m_networkEditorInterface = AZ::Interface<INetworking>::Get()->CreateNetworkInterface(
+        m_networkEditorInterface = AZ::Interface<INetworking>::Get()->CreateSystemNetworkInterface(
             editorInterfaceName, ProtocolType::Tcp, TrustZone::ExternalClientToServer, *this);
         m_networkEditorInterface->SetTimeoutMs(AZ::Time::ZeroTimeMs); // Disable timeouts on this network interface