Files
UnrealEngineUWP/Engine/Plugins/Experimental/PythonScriptPlugin/Source/PythonScriptPlugin/Private/PyConversion.h
Simon Tourangeau 614ad8db40 Copying //UE4/Dev-Enterprise to //UE4/Dev-Main (Source: //UE4/Dev-Enterprise @ 3797699)
#lockdown Nick.Penwarden
#rb JeanMichel.Dignard

============================
  MAJOR FEATURES & CHANGES
============================

Change 3770717 by Simon.Tourangeau

	Fix Blank Enterprise template project creation

Change 3773186 by Simon.Tourangeau

	Fix asset migration to correctly handle the migration of content from Content Plugins

Change 3773230 by JeanLuc.Corenthin

	Adding new material asset for CAD importer
	Removing old material assets for CAD importer

Change 3774391 by JeanMichel.Dignard

	Added support for IES asymmetrical light profile
	- IES textures are now 2D (256*256) and the shader will use the light tangent to sample the texture.
	- Point light tangent is now the Z axis to match the spot lights. Tube shaped point lights will be automatically rotated to compensate for this change. Dynamically generated point lights with a source length will need to have a 90 degrees pitch added to their orientation.

	#jira UEENT-55

Change 3775668 by JeanMichel.Dignard

	Fixed linux and mac editor builds. Use FVector::DotProduct instead of Dot3 since we're using FVectors.

Change 3781147 by Jamie.Dale

	[Python] Prevent the Xcode version of Python being used by default

Change 3781991 by JeanMichel.Dignard

	Send the IES texture profile to lightmass in a separate TArray to fix warning 6262 about using too much stack during static analysis.

Change 3783479 by Simon.Tourangeau

	Fix NewProjectWizard crash if starter content was enabled

	#jira UEENT-635

Change 3784279 by Jamie.Dale

	[Python] Added ScopedEditorTransaction and an editor specific module

Change 3787566 by JeanLuc.Corenthin

	Fixed issue with display of units which were not reflecting the project settings when enbling unit display.

	Got Jamie Dale to help me find the correct solution to this problem: a lambda function.

	Thanks, Jamie!

Change 3788178 by Martin.Sevigny

	Make sure that FLightPropagationVolume is properly initialized before using it. Can currently trigger a check in  FProjectedShadowInfo::SetupWholeSceneProjection because of an uninitialized BoundingBox if LPVIntensity is saved at 0.

	Solves: https://udn.unrealengine.com/questions/354040/switching-gi-lpvs-at-runtime.html

Change 3788301 by JeanLuc.Corenthin

	On behalf of Anousack:

	UE assets necessary to properly handle Cropped procedural textures.

	#jira UEENT-522

Change 3789146 by Martin.Sevigny

	Bringing back the LPVIntensity test as per MarcusW review.

Change 3789467 by Patrick.Boutot

	Add Analytics to PythonScriptPlugin.

Change 3789473 by Patrick.Boutot

	Add a slow task dialog when executing a Python script.

Change 3790809 by Patrick.Boutot

	Add GIsRunningUnattendedScript. If true, we are running an editor script that should not prompt any dialog modal. The default value of any model will be used. This is used when running a Blutility or script like Python and we don't want an OK dialog to pop while the script is running. Could be set for commandlet with -RUNNINGUNATTENDEDSCRIPT

Change 3790970 by Patrick.Boutot

	Add SavePackages with Dialog version in EditorLoadingAndSavingUtils. Refactor some internal save & checkout function in FileHelpers to prevent dialogs from showing when it was not requested.

Change 3790976 by Patrick.Boutot

	Add RenameAssetsWithDialog to AssetTools. All previous implementation now use the WithDialog version.
	Allow DeleteObject & DuplicatedAsset to be completed without dialog.

Change 3791597 by Simon.Tourangeau

	Fix custom window positions in "windowed mode"

	#jira UE-52873

Change 3791633 by Patrick.Boutot

	Expose to Blueprint the actor' label and folder path.

Change 3791634 by Patrick.Boutot

	Change size of the OutputLog's SuggestionList box.

Change 3791637 by Patrick.Boutot

	Make sure the suggestions panel is closed before executing the command. Some command wants to run dialog and the suggestions panel may prevent it from opening.

Change 3791661 by Jamie.Dale

	[Python] Fixed a bug where we could return an object of the incorrect type from the cache

	This could happen if the same instance pointer actually represented two different things, such as when a struct had a different struct as its first member as both of those have the same address, but reflect two different things.

	We now treat the type as significant in the cache, and only return something if it matches both the instance and the type.

	#jira UEENT-651

Change 3794968 by Patrick.Boutot

	Extend File menu to include Python menu. Save the last 10 scripts executed in the user config.

Change 3795084 by Jamie.Dale

	[Python] Added a way to purge all references to a given UObject (or set of UObjects) from any living Python objects

Change 3795324 by Jamie.Dale

	[Python] Ensure that Python objects referencing the current world/level are purged when the active world/level is changed

	This is needed to avoid a fatal assert about a GC leak

	#jira UEENT-658

Change 3796248 by Jamie.Dale

	FilterAssetDataWithNoTags no longer implicitly removes localized assets


Change 3773185 by Simon.Tourangeau

	Move DatasmithImporter plugin content to a content-only plugin under Engine/Plugins/Enterprise/DatasmithContent

	This makes it possible to load content created with the DatasmithImporter without having access to Enterprise plugins.

	#jira UEENT-544

Change 3790982 by Patrick.Boutot

	Set GIsRunningUnattendedScript to EditorScriptUtilities callable functions.
	Load level without a prompt.

Change 3791539 by Jamie.Dale

	[Python] Added ScriptName and ScriptNoExport meta-data to allow control over how things are exposed to scripts

	ScriptName can be used to override the basic name we use when converting classes, structs, enums, properties, and functions to their Python names. It has been used here to remove all the K2_ and BP_ prefixes, and to remove Kismet and Blueprint from some library names.

	ScriptNoExport can be used to prevent a property or function from exporting to Python. It has been used here to prevent exporting some deprecated functions that had names that would conflict if we stripped off the K2_ prefix of some newer functions (there were only a handful of these cases).

Change 3773163 by Patrick.Boutot

	Improve ConvertActors implementation. Check if the StaticMesh path is valid and do not use dialog in the case we are converting a Brush to a StaticMesh.

Change 3776401 by Patrick.Boutot

	Add function to spawn and destroy an actor in editor mode. Spawn use the Place functionality of the editor, you can spawn from an asset, class, archetype or factory.

Change 3778137 by Patrick.Boutot

	Add 2 functions to EditorAssetLibrary. GetPathNameForLoadedAsset, wrapper for UObject.GetPathName(). FindPackageReferencersForAsset similar to AssetRegistry.FindPackageReferencer. It will load the assets and all the referencers to confirm the reference.
	EditorAssetLibrary now support full path.

Change 3778139 by Patrick.Boutot

	Update example data for EditorScriptingUtilities.

Change 3778768 by Patrick.Boutot

	Update EditorScriptingUtilities py file with the new naming convention.

Change 3779291 by Patrick.Boutot

	Remove const& on TSubLassOf because Blueprint do not show the Pick tool  with it.
	Update py script & blueprint to point to the new paths.

Change 3783246 by Patrick.Boutot

	After review. Tech art prefer to have a filter that check the class and not have the class pass as argument for GetAllLevelActor.
	Fix return type in Blueprint for SpawnActorFromClass.

Change 3789367 by Patrick.Boutot

	Gets all TagValues associated with an asset as strings value.

Change 3789438 by Patrick.Boutot

	Split EditorLevelLibrary into EditorFilterLibrary. All filter function are now in their own modules.

Change 3789489 by Patrick.Boutot

	Update script examples with copyright and with the split from EditorFilterLibrary.

Change 3790980 by Patrick.Boutot

	Prevent all dialog modal from showing up when running a Python script via command line.

Change 3790984 by Patrick.Boutot

	Fix typo in content_browser.py. Delete asset with the loaded version. Fix double values initialized by float.

[CL 3797855 by Simon Tourangeau in Main branch]
2017-12-08 16:18:46 -05:00

205 lines
11 KiB
C++

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "IncludePython.h"
#include "PyConversionMethod.h"
#include "PyWrapperOwnerContext.h"
#include "UObject/Class.h"
#include "Templates/EnableIf.h"
#include "Templates/UnrealTemplate.h"
#include "Templates/PointerIsConvertibleFromTo.h"
#if WITH_PYTHON
/**
* Conversion between native and Python types.
* @note These functions may set error state when using ESetErrorState::Yes.
*/
namespace PyConversion
{
enum class ESetErrorState : uint8 { No, Yes };
/** bool overload */
bool Nativize(PyObject* PyObj, bool& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const bool Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** int8 overload */
bool Nativize(PyObject* PyObj, int8& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const int8 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** uint8 overload */
bool Nativize(PyObject* PyObj, uint8& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const uint8 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** int16 overload */
bool Nativize(PyObject* PyObj, int16& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const int16 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** uint16 overload */
bool Nativize(PyObject* PyObj, uint16& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const uint16 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** int32 overload */
bool Nativize(PyObject* PyObj, int32& OutVal, const ESetErrorState ErrorState = ESetErrorState::Yes);
bool Pythonize(const int32 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** uint32 overload */
bool Nativize(PyObject* PyObj, uint32& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const uint32 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** int64 overload */
bool Nativize(PyObject* PyObj, int64& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const int64 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** uint64 overload */
bool Nativize(PyObject* PyObj, uint64& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const uint64 Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** float overload */
bool Nativize(PyObject* PyObj, float& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const float Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** double overload */
bool Nativize(PyObject* PyObj, double& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const double Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** FString overload */
bool Nativize(PyObject* PyObj, FString& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const FString& Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** FName overload */
bool Nativize(PyObject* PyObj, FName& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const FName& Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** FText overload */
bool Nativize(PyObject* PyObj, FText& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(const FText& Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** UObject overload */
bool Nativize(PyObject* PyObj, UObject*& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool Pythonize(UObject* Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** Conversion for object types, including optional type checking */
bool NativizeObject(PyObject* PyObj, UObject*& OutVal, UClass* ExpectedType, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool PythonizeObject(UObject* Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
PyObject* PythonizeObject(UObject* Val, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** Conversion for class types, including optional type checking */
bool NativizeClass(PyObject* PyObj, UClass*& OutVal, UClass* ExpectedType, const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool PythonizeClass(UClass* Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes);
PyObject* PythonizeClass(UClass* Val, const ESetErrorState SetErrorState = ESetErrorState::Yes);
namespace Internal
{
/** Internal version of NativizeStruct/PythonizeStruct that work on the type-erased data */
bool NativizeStruct(PyObject* PyObj, UScriptStruct* StructType, void* StructInstance, const ESetErrorState SetErrorState);
bool PythonizeStruct(UScriptStruct* StructType, const void* StructInstance, PyObject*& OutPyObj, const ESetErrorState SetErrorState);
/** Dummy catch-all for type conversions that aren't yet implemented */
template <typename T, typename Spec = void>
struct FTypeConv
{
static bool Nativize(PyObject* PyObj, T& OutVal, const ESetErrorState SetErrorState)
{
ensureAlwaysMsgf(false, TEXT("Nativize not implemented for type"));
return false;
}
static bool Pythonize(const T& Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState)
{
ensureAlwaysMsgf(false, TEXT("Pythonize not implemented for type"));
return false;
}
};
/** Override the catch-all for UObject types */
template <typename T>
struct FTypeConv<T, typename TEnableIf<TPointerIsConvertibleFromTo<typename TRemovePointer<T>::Type, UObject>::Value>::Type>
{
static bool Nativize(PyObject* PyObj, T& OutVal, const ESetErrorState SetErrorState)
{
return PyConversion::NativizeObject(PyObj, (UObject*&)OutVal, TRemovePointer<T>::Type::StaticClass(), SetErrorState);
}
static bool Pythonize(const T& Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState)
{
return PyConversion::PythonizeObject((UObject*)Val, OutPyObj, SetErrorState);
}
};
}
/**
* Generic version of Nativize used if there is no matching overload.
* Used to allow conversion from object and struct types that don't match a specific override (see FTypeConv).
*/
template <typename T>
bool Nativize(PyObject* PyObj, T& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes)
{
return Internal::FTypeConv<T>::Nativize(PyObj, OutVal, SetErrorState);
}
/**
* Generic version of Pythonize used if there is no matching overload.
* Used to allow conversion from object and struct types that don't match a specific override (see FTypeConv).
*/
template <typename T>
bool Pythonize(const T& Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes)
{
return Internal::FTypeConv<T>::Pythonize(Val, OutPyObj, SetErrorState);
}
/** Generic version of Pythonize that returns a PyObject rather than a bool */
template <typename T>
PyObject* Pythonize(const T& Val, const ESetErrorState SetErrorState = ESetErrorState::Yes)
{
PyObject* Obj = nullptr;
Pythonize(Val, Obj, SetErrorState);
return Obj;
}
/** Conversion for known struct types */
template <typename T>
bool NativizeStruct(PyObject* PyObj, T& OutVal, const ESetErrorState SetErrorState = ESetErrorState::Yes)
{
return Internal::NativizeStruct(PyObj, TBaseStructure<T>::Get(), &OutVal, SetErrorState);
}
/** Conversion for known struct types */
template <typename T>
bool PythonizeStruct(const T& Val, PyObject*& OutPyObj, const ESetErrorState SetErrorState = ESetErrorState::Yes)
{
return Internal::PythonizeStruct(TBaseStructure<T>::Get(), &Val, OutPyObj, SetErrorState);
}
/** Conversion for known struct types that returns a PyObject rather than a bool */
template <typename T>
PyObject* PythonizeStruct(const T& Val, const ESetErrorState SetErrorState = ESetErrorState::Yes)
{
PyObject* Obj = nullptr;
Internal::PythonizeStruct(TBaseStructure<T>::Get(), &Val, Obj, SetErrorState);
return Obj;
}
/** Conversion for property instances (including fixed arrays) - ValueAddr should point to the property data */
bool NativizeProperty(PyObject* PyObj, const UProperty* Prop, void* ValueAddr, const FPyWrapperOwnerContext& InChangeOwner = FPyWrapperOwnerContext(), const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool PythonizeProperty(const UProperty* Prop, const void* ValueAddr, PyObject*& OutPyObj, const EPyConversionMethod ConversionMethod = EPyConversionMethod::Copy, PyObject* OwnerPyObj = nullptr, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** Conversion for single property instances - ValueAddr should point to the property data */
bool NativizeProperty_Direct(PyObject* PyObj, const UProperty* Prop, void* ValueAddr, const FPyWrapperOwnerContext& InChangeOwner = FPyWrapperOwnerContext(), const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool PythonizeProperty_Direct(const UProperty* Prop, const void* ValueAddr, PyObject*& OutPyObj, const EPyConversionMethod ConversionMethod = EPyConversionMethod::Copy, PyObject* OwnerPyObj = nullptr, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/** Conversion for property instances within a structure (including fixed arrays) - BaseAddr should point to the structure data */
bool NativizeProperty_InContainer(PyObject* PyObj, const UProperty* Prop, void* BaseAddr, const int32 ArrayIndex, const FPyWrapperOwnerContext& InChangeOwner = FPyWrapperOwnerContext(), const ESetErrorState SetErrorState = ESetErrorState::Yes);
bool PythonizeProperty_InContainer(const UProperty* Prop, const void* BaseAddr, const int32 ArrayIndex, PyObject*& OutPyObj, const EPyConversionMethod ConversionMethod = EPyConversionMethod::Copy, PyObject* OwnerPyObj = nullptr, const ESetErrorState SetErrorState = ESetErrorState::Yes);
/**
* Helper function used to emit property change notifications as value changes are made
* This function should be called when you know the value will actually change (or know you want to emit the notifications for it changing) and will do
* the pre-change notify, invoke the passed delegate to perform the change, then do the post-change notify
*/
void EmitPropertyChangeNotifications(const FPyWrapperOwnerContext& InChangeOwner, const TFunctionRef<void()>& InDoChangeFunc);
}
#endif // WITH_PYTHON