/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ #pragma once #include #include #include #include #include #include namespace AZ { struct BehaviorParameter; struct BehaviorValueParameter; class BehaviorMethod; } namespace EditorPythonBindings { namespace Scope { inline bool IsBehaviorFlaggedForEditor(const AZ::AttributeArray& attributes) { // defaults to Launcher AZ::Script::Attributes::ScopeFlags scopeType = AZ::Script::Attributes::ScopeFlags::Launcher; AZ::Attribute* scopeAttribute = AZ::FindAttribute(AZ::Script::Attributes::Scope, attributes); if (scopeAttribute) { AZ::AttributeReader scopeAttributeReader(nullptr, scopeAttribute); scopeAttributeReader.Read(scopeType); } return (scopeType == AZ::Script::Attributes::ScopeFlags::Automation || scopeType == AZ::Script::Attributes::ScopeFlags::Common); } inline void FetchScriptName(const AZ::AttributeArray& attributes, AZStd::string& baseName) { AZ::Attribute* scriptNameAttribute = AZ::FindAttribute(AZ::Script::Attributes::Alias, attributes); if (scriptNameAttribute) { AZ::AttributeReader scopeAttributeReader(nullptr, scriptNameAttribute); scopeAttributeReader.Read(baseName); } } } namespace Module { using PackageMapType = AZStd::unordered_map; //! Finds or creates a sub-module to add a base parent module; create all the sub-modules as well //! @param modulePackageMap keeps track of the known modules //! @param moduleName can be a dot separated string such as "mygen.mypackage.mymodule" //! @param parentModule the module to add new sub-modules //! @param fallbackModule the module to add new sub-modules //! @param alertUsingFallback issue a warning if using the fallback module //! @return the new submodule pybind11::module DeterminePackageModule(PackageMapType& modulePackageMap, AZStd::string_view moduleName, pybind11::module parentModule, pybind11::module fallbackModule, bool alertUsingFallback); inline AZStd::optional GetName(const AZ::AttributeArray& attributes) { AZ::Attribute* moduleAttribute = AZ::FindAttribute(AZ::Script::Attributes::Module, attributes); if (moduleAttribute) { const char* moduleName = nullptr; AZ::AttributeReader scopeAttributeReader(nullptr, moduleAttribute); scopeAttributeReader.Read(moduleName); if (moduleName) { return { moduleName }; } } return {}; } } namespace Convert { // allocation pattern for BehaviorValueParameters being stored in the stack and needs to be cleaned at the end of a block using VariableDeleter = AZStd::function; struct StackVariableAllocator final : public AZStd::static_buffer_allocator<256, 16> { public: ~StackVariableAllocator(); void StoreVariableDeleter(VariableDeleter&& deleter); private: AZStd::vector m_cleanUpItems; }; //! Converts a behavior value parameter to a Python object //! @param behaviorValue is a parameter that came from a result or some prepared behavior value //! @param stackVariableAllocator manages the allocated parameter while in scope //! @return a valid Python object or None if no conversion was possible pybind11::object BehaviorValueParameterToPython(AZ::BehaviorValueParameter& behaviorValue, Convert::StackVariableAllocator& stackVariableAllocator); //! Converts Python object to a behavior value parameter using an existing behaviorArgument from a Behavior Method //! @param behaviorArgument the stored argument slot from a Behavior Method to match with the pyObj to covert in the parameter //! @param parameter is the output of the conversion from Python to a Behavior value //! @param stackVariableAllocator manages the allocated parameter while in scope //! @return true if the conversion happened bool PythonToBehaviorValueParameter(const AZ::BehaviorParameter& behaviorArgument, pybind11::object pyObj, AZ::BehaviorValueParameter& parameter, Convert::StackVariableAllocator& stackVariableAllocator); //! Converts Python object to a PythonProxyObject, if possible //! @param behaviorArgument A stored PythonProxyObject in Python, returns FALSE if the Python object does not point to a PythonProxyObject //! @param parameter is the output of the conversion from Python to a Behavior value //! @return true if the conversion happened bool PythonProxyObjectToBehaviorValueParameter(const AZ::BehaviorParameter& behaviorArgument, pybind11::object pyObj, AZ::BehaviorValueParameter& parameter); //! Gets a readable type name for the Python object; this will unwrap a PythonProxyObject to find its underlying type name //! @param pyObj any valid Python object value //! @return text form of the Python object value type AZStd::string GetPythonTypeName(pybind11::object pyObj); } namespace Call { //! Calls a BehaviorMethod with a tuple of arguments for non-member functions pybind11::object StaticMethod(AZ::BehaviorMethod* behaviorMethod, pybind11::args args); //! Calls a BehaviorMethod with a tuple of arguments for member class level functions pybind11::object ClassMethod(AZ::BehaviorMethod* behaviorMethod, AZ::BehaviorObject self, pybind11::args args); } }