Przeglądaj źródła

Multiplayer Compression System Component Dependency Crash Fix (#18572)

* Multiplayer Compression requires NetworkSystemComponent to function. Fixes a crash on startup when Compression tries to call AZ::Interface<AzNetworking::INetworking>::Get() but receives a nullptr

Signed-off-by: AMZN-Gene <[email protected]>

* Moved MultiplayerCompression registration from constructor into Activate(). Activate() ensues NetworkSystemComponent is activate too. Component constructor order is not guarenteed.

Signed-off-by: AMZN-Gene <[email protected]>

* Init pointer to nullptr

Signed-off-by: AMZN-Gene <[email protected]>

* INetwork becomes the lifetime owner of the compression factory

Signed-off-by: AMZN-Gene <[email protected]>

* Update Gems/MultiplayerCompression/Code/Source/MultiplayerCompressionSystemComponent.cpp

Signed-off-by: Gene Walters <[email protected]>

---------

Signed-off-by: AMZN-Gene <[email protected]>
Signed-off-by: Gene Walters <[email protected]>
Gene Walters 8 miesięcy temu
rodzic
commit
ef7704e655

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

@@ -57,6 +57,7 @@ namespace AzNetworking
         virtual bool DestroyNetworkInterface(const AZ::Name& name) = 0;
 
         //! Registers a Compressor Factory that can be used to create compressors for INetworkInterfaces
+        //! Upon registry, INetworking assumes ownership of the factory pointer.
         //! @param factory The ICompressorFactory to register
         virtual void RegisterCompressorFactory(ICompressorFactory* factory) = 0;
 

+ 13 - 6
Gems/MultiplayerCompression/Code/Source/MultiplayerCompressionSystemComponent.cpp

@@ -46,15 +46,22 @@ namespace MultiplayerCompression
         incompatible.push_back(AZ_CRC_CE("MultiplayerCompressionService"));
     }
 
-    MultiplayerCompressionSystemComponent::MultiplayerCompressionSystemComponent()
+    void MultiplayerCompressionSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required)
     {
-        m_multiplayerCompressionFactory = new MultiplayerCompressionFactory();
-        AZ::Interface<AzNetworking::INetworking>::Get()->RegisterCompressorFactory(m_multiplayerCompressionFactory);
+        required.push_back(AZ_CRC_CE("NetworkingService"));  // Required for getting AzNetworking::INetworking interface
     }
 
-    MultiplayerCompressionSystemComponent::~MultiplayerCompressionSystemComponent()
+    void MultiplayerCompressionSystemComponent::Activate()
     {
-        AZ::Interface<AzNetworking::INetworking>::Get()->UnregisterCompressorFactory(m_multiplayerCompressionFactory->GetFactoryName());
-        delete m_multiplayerCompressionFactory;
+        // The registering class is responsible for managing the lifetime of the factory.
+        // We'll save the factory name required for unregistering later, but not manage the pointer ourselves.
+        auto* compressionFactory = new MultiplayerCompressionFactory();
+        m_multiplayerCompressionFactoryName = compressionFactory->GetFactoryName();
+        AZ::Interface<AzNetworking::INetworking>::Get()->RegisterCompressorFactory(compressionFactory);
+    }
+
+    void MultiplayerCompressionSystemComponent::Deactivate()
+    {
+        AZ::Interface<AzNetworking::INetworking>::Get()->UnregisterCompressorFactory(m_multiplayerCompressionFactoryName);
     }
 }

+ 6 - 5
Gems/MultiplayerCompression/Code/Source/MultiplayerCompressionSystemComponent.h

@@ -25,21 +25,22 @@ namespace MultiplayerCompression
     public:
         AZ_COMPONENT(MultiplayerCompressionSystemComponent, "{C3099AC9-47A6-41D2-8928-F38F904BAC1B}");
 
-        MultiplayerCompressionSystemComponent();
-        ~MultiplayerCompressionSystemComponent() override;
+        MultiplayerCompressionSystemComponent() = default;
+        ~MultiplayerCompressionSystemComponent() override = default;
 
         static void Reflect(AZ::ReflectContext* context);
 
         static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided);
         static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible);
+        static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required);
 
         ////////////////////////////////////////////////////////////////////////
         // AZ::Component interface implementation
         void Init() override {}
-        void Activate() override {}
-        void Deactivate() override {}
+        void Activate() override;
+        void Deactivate() override;
         ////////////////////////////////////////////////////////////////////////
     private:
-        MultiplayerCompressionFactory* m_multiplayerCompressionFactory;
+        AZStd::string_view m_multiplayerCompressionFactoryName;
     };
 }