Procházet zdrojové kódy

{LYN-2336} Fix: Python Console script help opens empty (#3060)

* {LYN-2336} Fix: Python Console script help opens empty

Fixes: Python Console: Script Help opens empty in AutomatedTesting project
This fixes the missing Python symbols in the Editor
This also fixes the PYI files to write out for the AutomatedTesting project

Signed-off-by: Jackson <[email protected]>

* Fixing proper symbol log execution times


Signed-off-by: Jackson <[email protected]>

* annotating input values with const

Signed-off-by: Jackson <[email protected]>
jackalbe před 4 roky
rodič
revize
117bd0e680

+ 19 - 6
Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp

@@ -90,6 +90,11 @@ namespace EditorPythonBindings
         PythonSymbolEventBus::Handler::BusConnect();
         EditorPythonBindingsNotificationBus::Handler::BusConnect();
         AZ::Interface<AzToolsFramework::EditorPythonConsoleInterface>::Register(this);
+
+        if (PythonSymbolEventBus::GetTotalNumOfEventHandlers() > 1)
+        {
+            OnPostInitialize();
+        }
     }
 
     void PythonLogSymbolsComponent::Deactivate()
@@ -111,6 +116,7 @@ namespace EditorPythonBindings
             m_basePath = pythonSymbolsPath;
         }
         EditorPythonBindingsNotificationBus::Handler::BusDisconnect();
+        PythonSymbolEventBus::ExecuteQueuedEvents();
     }
 
     void PythonLogSymbolsComponent::WriteMethod(AZ::IO::HandleType handle, AZStd::string_view methodName, const AZ::BehaviorMethod& behaviorMethod, const AZ::BehaviorClass* behaviorClass)
@@ -206,12 +212,12 @@ namespace EditorPythonBindings
         AZ::IO::FileIOBase::GetInstance()->Write(handle, buffer.c_str(), buffer.size());
     }
 
-    void PythonLogSymbolsComponent::LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass)
+    void PythonLogSymbolsComponent::LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass)
     {
         LogClassWithName(moduleName, behaviorClass, behaviorClass->m_name.c_str());
     }
 
-    void PythonLogSymbolsComponent::LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className)
+    void PythonLogSymbolsComponent::LogClassWithName(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass, const AZStd::string className)
     {
         Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
         if (fileHandle.IsValid())
@@ -255,7 +261,11 @@ namespace EditorPythonBindings
         }
     }
 
-    void PythonLogSymbolsComponent::LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod)
+    void PythonLogSymbolsComponent::LogClassMethod(
+        const AZStd::string moduleName,
+        const AZStd::string globalMethodName,
+        const AZ::BehaviorClass* behaviorClass,
+        const AZ::BehaviorMethod* behaviorMethod)
     {
         AZ_UNUSED(behaviorClass);
         Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
@@ -265,7 +275,7 @@ namespace EditorPythonBindings
         }
     }
 
-    void PythonLogSymbolsComponent::LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus)
+    void PythonLogSymbolsComponent::LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus)
     {
         if (behaviorEBus->m_events.empty())
         {
@@ -404,7 +414,7 @@ namespace EditorPythonBindings
         }
     }
 
-    void PythonLogSymbolsComponent::LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod)
+    void PythonLogSymbolsComponent::LogGlobalMethod(const AZStd::string moduleName, const AZStd::string methodName, const AZ::BehaviorMethod* behaviorMethod)
     {
         Internal::FileHandle fileHandle(OpenModuleAt(moduleName));
         if (fileHandle.IsValid())
@@ -428,7 +438,10 @@ namespace EditorPythonBindings
         }
     }
 
-    void PythonLogSymbolsComponent::LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty)
+    void PythonLogSymbolsComponent::LogGlobalProperty(
+        const AZStd::string moduleName,
+        const AZStd::string propertyName,
+        const AZ::BehaviorProperty* behaviorProperty)
     {
         if (!behaviorProperty->m_getter || !behaviorProperty->m_getter->GetResult())
         {

+ 13 - 6
Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h

@@ -51,12 +51,19 @@ namespace EditorPythonBindings
 
         ////////////////////////////////////////////////////////////////////////
         // PythonSymbolEventBus::Handler
-        void LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass) override;
-        void LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className) override;
-        void LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod) override;
-        void LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus) override;
-        void LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod) override;
-        void LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty) override;
+        void LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass) override;
+        void LogClassWithName(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass, const AZStd::string className) override;
+        void LogClassMethod(
+            const AZStd::string moduleName,
+            const AZStd::string globalMethodName,
+            const AZ::BehaviorClass* behaviorClass,
+            const AZ::BehaviorMethod* behaviorMethod) override;
+        void LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus) override;
+        void LogGlobalMethod(const AZStd::string moduleName, const AZStd::string methodName, const AZ::BehaviorMethod* behaviorMethod) override;
+        void LogGlobalProperty(
+            const AZStd::string moduleName,
+            const AZStd::string propertyName,
+            const AZ::BehaviorProperty* behaviorProperty) override;
         void Finalize() override;
         AZStd::string FetchPythonTypeName(const AZ::BehaviorParameter& param) override;
 

+ 1 - 1
Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp

@@ -394,7 +394,7 @@ namespace EditorPythonBindings
 
                     // log the bus symbol
                     AZStd::string subModuleName = pybind11::cast<AZStd::string>(thisBusModule.attr("__name__"));
-                    PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus);
+                    PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus);
                 }
             }
 

+ 4 - 4
Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp

@@ -756,7 +756,7 @@ namespace EditorPythonBindings
                             }
 
                             AZStd::string subModuleName = pybind11::cast<AZStd::string>(subModule.attr("__name__"));
-                            PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClassMethod, subModuleName, globalMethodName, behaviorClass, behaviorMethod);
+                            PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClassMethod, subModuleName, globalMethodName, behaviorClass, behaviorMethod);
                         }
                         else
                         {
@@ -782,7 +782,7 @@ namespace EditorPythonBindings
                         pybind11::setattr(subModule, constantPropertyName.c_str(), constantValue);
 
                         AZStd::string subModuleName = pybind11::cast<AZStd::string>(subModule.attr("__name__"));
-                        PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, constantPropertyName, behaviorProperty);
+                        PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, constantPropertyName, behaviorProperty);
                     }
                 }
 
@@ -809,11 +809,11 @@ namespace EditorPythonBindings
                         {
                             return ConstructPythonProxyObjectByTypename(behaviorClassName, pythonArgs);
                         });
-                        PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClassWithName, subModuleName, behaviorClass, properSyntax);
+                        PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClassWithName, subModuleName, behaviorClass, properSyntax);
                     }
                     else
                     {
-                        PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogClass, subModuleName, behaviorClass);
+                        PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogClass, subModuleName, behaviorClass);
                     }
                 }
             }

+ 4 - 4
Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp

@@ -153,7 +153,7 @@ namespace EditorPythonBindings
                     StaticPropertyHolderMapEntry& entry = iter->second;
                     entry.second->AddProperty(propertyName, behaviorProperty);
                 }
-                PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, scopeName, propertyName, behaviorProperty);
+                PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, scopeName, propertyName, behaviorProperty);
             }
 
             pybind11::module DetermineScope(pybind11::module scope, const AZStd::string& fullName)
@@ -302,7 +302,7 @@ namespace EditorPythonBindings
 
                 // log global method symbol
                 AZStd::string subModuleName = pybind11::cast<AZStd::string>(targetModule.attr("__name__"));
-                PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalMethod, subModuleName, methodName, behaviorMethod);
+                PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalMethod, subModuleName, methodName, behaviorMethod);
             }
         }
 
@@ -325,7 +325,7 @@ namespace EditorPythonBindings
 
                 //  log global property symbol
                 AZStd::string subModuleName = pybind11::cast<AZStd::string>(globalsModule.attr("__name__"));
-                PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, propertyName, behaviorProperty);
+                PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogGlobalProperty, subModuleName, propertyName, behaviorProperty);
 
                 if (behaviorProperty->m_getter && behaviorProperty->m_setter)
                 {
@@ -377,7 +377,7 @@ namespace EditorPythonBindings
             PythonProxyBusManagement::CreateSubmodule(parentModule);
             Internal::RegisterPaths(parentModule);
 
-            PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::Finalize);
+            PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::Finalize);
         }
     }
 }

+ 30 - 6
Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h

@@ -9,6 +9,14 @@
 
 #include <AzCore/EBus/EBus.h>
 
+namespace AZ
+{
+    class BehaviorClass;
+    class BehaviorMethod;
+    class BehaviorEBus;
+    class BehaviorProperty;
+}
+
 namespace EditorPythonBindings
 {
     //! An interface to track exported Python symbols 
@@ -16,23 +24,39 @@ namespace EditorPythonBindings
         : public AZ::EBusTraits
     {
     public:
+        // the symbols will be written out in the future
+        static const bool EnableEventQueue = true;
+
         //! logs a behavior class type
-        virtual void LogClass(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass) = 0;
+        virtual void LogClass(const AZStd::string moduleName, const AZ::BehaviorClass* behaviorClass) = 0;
 
         //! logs a behavior class type with an override to its name
-        virtual void LogClassWithName(AZStd::string_view moduleName, AZ::BehaviorClass* behaviorClass, AZStd::string_view className) = 0;
+        virtual void LogClassWithName(
+            const AZStd::string moduleName,
+            const AZ::BehaviorClass* behaviorClass,
+            const AZStd::string className) = 0;
 
         //! logs a static class method with a specified global method name
-        virtual void LogClassMethod(AZStd::string_view moduleName, AZStd::string_view globalMethodName, AZ::BehaviorClass* behaviorClass, AZ::BehaviorMethod* behaviorMethod) = 0;
+        virtual void LogClassMethod(
+            const AZStd::string moduleName,
+            const AZStd::string globalMethodName,
+            const AZ::BehaviorClass* behaviorClass,
+            const AZ::BehaviorMethod* behaviorMethod) = 0;
 
         //! logs a behavior bus with a specified bus name
-        virtual void LogBus(AZStd::string_view moduleName, AZStd::string_view busName, AZ::BehaviorEBus* behaviorEBus) = 0;
+        virtual void LogBus(const AZStd::string moduleName, const AZStd::string busName, const AZ::BehaviorEBus* behaviorEBus) = 0;
 
         //! logs a global method from the behavior context registry with a specified method name
-        virtual void LogGlobalMethod(AZStd::string_view moduleName, AZStd::string_view methodName, AZ::BehaviorMethod* behaviorMethod) = 0;
+        virtual void LogGlobalMethod(
+            const AZStd::string moduleName,
+            const AZStd::string methodName,
+            const AZ::BehaviorMethod* behaviorMethod) = 0;
 
         //! logs a global property, enum, or constant from the behavior context registry with a specified property name
-        virtual void LogGlobalProperty(AZStd::string_view moduleName, AZStd::string_view propertyName, AZ::BehaviorProperty* behaviorProperty) = 0;
+        virtual void LogGlobalProperty(
+            const AZStd::string moduleName,
+            const AZStd::string propertyName,
+            const  AZ::BehaviorProperty* behaviorProperty) = 0;
 
         //! signals the end of the logging of symbols
         virtual void Finalize() = 0;

+ 39 - 3
Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp

@@ -10,6 +10,7 @@
 #include <EditorPythonBindings/EditorPythonBindingsBus.h>
 
 #include <Source/PythonCommon.h>
+#include <Source/PythonSymbolsBus.h>
 #include <pybind11/pybind11.h>
 #include <pybind11/embed.h>
 #include <pybind11/eval.h>
@@ -25,6 +26,7 @@
 #include <AzCore/Serialization/SerializeContext.h>
 #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
 #include <AzCore/std/string/conversions.h>
+#include <AzCore/std/smart_ptr/make_shared.h>
 #include <AzCore/StringFunc/StringFunc.h>
 #include <AzCore/Utils/Utils.h>
 
@@ -39,7 +41,7 @@
 
 namespace Platform
 {
-    // Implemented in each different platform's implentation files, as it differs per platform.
+    // Implemented in each different platform's implementation files, as it differs per platform.
     bool InsertPythonBinaryLibraryPaths(AZStd::unordered_set<AZStd::string>& paths, const char* pythonPackage, const char* engineRoot);
     AZStd::string GetPythonHomePath(const char* pythonPackage, const char* engineRoot);
 }
@@ -225,6 +227,37 @@ namespace RedirectOutput
 
 namespace EditorPythonBindings
 {
+    // A stand in bus to capture the log symbol queue events
+    // so that when/if the PythonLogSymbolsComponent becomes
+    // active it can write out the python symbols to disk
+    class PythonSystemComponent::SymbolLogHelper final
+        : public PythonSymbolEventBus::Handler
+    {
+    public:
+        SymbolLogHelper()
+        {
+            PythonSymbolEventBus::Handler::BusConnect();
+        }
+
+        ~SymbolLogHelper()
+        {
+            PythonSymbolEventBus::ExecuteQueuedEvents();
+            PythonSymbolEventBus::Handler::BusDisconnect();
+        }
+
+        void LogClass(const AZStd::string, const AZ::BehaviorClass*) override {}
+        void LogClassWithName(const AZStd::string, const AZ::BehaviorClass*, const AZStd::string) override {}
+        void LogClassMethod(
+            const AZStd::string,
+            const AZStd::string,
+            const AZ::BehaviorClass*,
+            const AZ::BehaviorMethod*) override {}
+        void LogBus(const AZStd::string, const AZStd::string, const AZ::BehaviorEBus*) override {}
+        void LogGlobalMethod(const AZStd::string, const AZStd::string, const AZ::BehaviorMethod*) override {}
+        void LogGlobalProperty(const AZStd::string, const AZStd::string, const AZ::BehaviorProperty*) override {}
+        void Finalize() override {}
+    };
+
     void PythonSystemComponent::Reflect(AZ::ReflectContext* context)
     {
         if (AZ::SerializeContext* serialize = azrtti_cast<AZ::SerializeContext*>(context))
@@ -471,8 +504,6 @@ namespace EditorPythonBindings
         }
     }
 
-
-
     bool PythonSystemComponent::StartPythonInterpreter(const PythonPathStack& pythonPathStack)
     {
         AZStd::unordered_set<AZStd::string> pyPackageSites(pythonPathStack.begin(), pythonPathStack.end());
@@ -520,6 +551,11 @@ namespace EditorPythonBindings
             AZStd::lock_guard<decltype(m_lock)> lock(m_lock);
             pybind11::gil_scoped_acquire acquire;
 
+            if (EditorPythonBindings::PythonSymbolEventBus::GetTotalNumOfEventHandlers() == 0)
+            {
+                m_symbolLogHelper = AZStd::make_shared<PythonSystemComponent::SymbolLogHelper>();
+            }
+
             // print Python version using AZ logging
             const int verRet = PyRun_SimpleStringFlags("import sys \nprint (sys.version) \n", nullptr);
             AZ_Error("python", verRet == 0, "Error trying to fetch the version number in Python!");

+ 3 - 0
Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h

@@ -59,10 +59,13 @@ namespace EditorPythonBindings
         ////////////////////////////////////////////////////////////////////////
         
     private:
+        class SymbolLogHelper;
+
         // handle multiple Python initializers and threads
         AZStd::atomic_int m_initalizeWaiterCount {0};
         AZStd::semaphore m_initalizeWaiter;
         AZStd::recursive_mutex m_lock;
+        AZStd::shared_ptr<SymbolLogHelper> m_symbolLogHelper;
     
         enum class Result
         {