From 117bd0e680d6af8b4f6df98e0d9030f12fb62be3 Mon Sep 17 00:00:00 2001 From: jackalbe <23512001+jackalbe@users.noreply.github.com> Date: Thu, 12 Aug 2021 11:19:15 -0500 Subject: [PATCH] {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 <23512001+jackalbe@users.noreply.github.com> * Fixing proper symbol log execution times Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com> * annotating input values with const Signed-off-by: Jackson <23512001+jackalbe@users.noreply.github.com> --- .../Code/Source/PythonLogSymbolsComponent.cpp | 25 ++++++++--- .../Code/Source/PythonLogSymbolsComponent.h | 19 ++++++--- .../Code/Source/PythonProxyBus.cpp | 2 +- .../Code/Source/PythonProxyObject.cpp | 8 ++-- .../Code/Source/PythonReflectionComponent.cpp | 8 ++-- .../Code/Source/PythonSymbolsBus.h | 36 +++++++++++++--- .../Code/Source/PythonSystemComponent.cpp | 42 +++++++++++++++++-- .../Code/Source/PythonSystemComponent.h | 3 ++ 8 files changed, 113 insertions(+), 30 deletions(-) diff --git a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp index 221e1fdcea..d39ca83000 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp +++ b/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.cpp @@ -90,6 +90,11 @@ namespace EditorPythonBindings PythonSymbolEventBus::Handler::BusConnect(); EditorPythonBindingsNotificationBus::Handler::BusConnect(); AZ::Interface::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()) { diff --git a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h b/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h index 54285198cf..5fbd1c3f37 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonLogSymbolsComponent.h +++ b/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; diff --git a/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp b/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp index 89f8248202..e640778bbe 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp +++ b/Gems/EditorPythonBindings/Code/Source/PythonProxyBus.cpp @@ -394,7 +394,7 @@ namespace EditorPythonBindings // log the bus symbol AZStd::string subModuleName = pybind11::cast(thisBusModule.attr("__name__")); - PythonSymbolEventBus::Broadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus); + PythonSymbolEventBus::QueueBroadcast(&PythonSymbolEventBus::Events::LogBus, subModuleName, ebusName, behaviorEBus); } } diff --git a/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp b/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp index de8009830b..706ca48156 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp +++ b/Gems/EditorPythonBindings/Code/Source/PythonProxyObject.cpp @@ -756,7 +756,7 @@ namespace EditorPythonBindings } AZStd::string subModuleName = pybind11::cast(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(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); } } } diff --git a/Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp index 0404e81380..38e00e73ed 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonReflectionComponent.cpp +++ b/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(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(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); } } } diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h b/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h index 242225e87a..9c6d3bab37 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h +++ b/Gems/EditorPythonBindings/Code/Source/PythonSymbolsBus.h @@ -9,6 +9,14 @@ #include +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; diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp index 32411e9417..8df196e7cb 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp +++ b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include #include @@ -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& 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(context)) @@ -471,8 +504,6 @@ namespace EditorPythonBindings } } - - bool PythonSystemComponent::StartPythonInterpreter(const PythonPathStack& pythonPathStack) { AZStd::unordered_set pyPackageSites(pythonPathStack.begin(), pythonPathStack.end()); @@ -520,6 +551,11 @@ namespace EditorPythonBindings AZStd::lock_guard lock(m_lock); pybind11::gil_scoped_acquire acquire; + if (EditorPythonBindings::PythonSymbolEventBus::GetTotalNumOfEventHandlers() == 0) + { + m_symbolLogHelper = AZStd::make_shared(); + } + // 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!"); diff --git a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h b/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h index 679da3ccab..48ac27a036 100644 --- a/Gems/EditorPythonBindings/Code/Source/PythonSystemComponent.h +++ b/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 m_symbolLogHelper; enum class Result {