You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
If a child anim BP is made and is saved without saving its parent, then when the class is reloaded later it will not be able to find the parent's sparse class data in the linker (as it will have been generated again from scratch on load, which doesnt patch the linker until the asset is resaved). This leads to serialization size mismatches. To address this (and because the sparse class data will always be regenerated as part of compile-on-load), we skip the portion of the CDO's archive that represents the serialized sparse class data if it is null after serialization. It can of course be legitimately null in a lot of cases (say a regular actor Blueprint), but this should have no ill effects and effectively be a seek to the current archive offset. This CL also fixes a number of child anim BP-related issues. First of all it prevents a crash when accessing out-of-bounds AnimNodeData by ensuring it is correctly duplicated in all circumstances. It also correctly propogates values from root->child sparse class data (in the same manner that anim node data used to be propogated before). This deals with compile-on-load issues where the child classes sparse class data is regenerated without serializing the parent classes sparse class data (see crash fix above). #jira UE-114674 - Creating a new child anim BP crashes #rb Fred.Kimberley,Phillip.Kavan,Jurre.deBaare [CL 16313070 by Thomas Sarkanen in ue5-main branch]
212 lines
9.5 KiB
C++
212 lines
9.5 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "KismetCompiler.h"
|
|
#include "Animation/AnimNodeBase.h"
|
|
#include "AnimGraphNode_Base.h"
|
|
#include "KismetCompilerModule.h"
|
|
#include "IAnimBlueprintCompilerCreationContext.h"
|
|
#include "Containers/ArrayView.h"
|
|
#include "IAnimBlueprintCompilationContext.h"
|
|
|
|
class UAnimationGraphSchema;
|
|
class UAnimGraphNode_SaveCachedPose;
|
|
class UAnimGraphNode_StateMachineBase;
|
|
class UAnimGraphNode_StateResult;
|
|
class UAnimGraphNode_CustomProperty;
|
|
|
|
class UAnimGraphNode_UseCachedPose;
|
|
class UAnimStateTransitionNode;
|
|
class UK2Node_CallFunction;
|
|
|
|
//
|
|
// Forward declarations.
|
|
//
|
|
class UAnimGraphNode_SaveCachedPose;
|
|
class UAnimGraphNode_UseCachedPose;
|
|
class UAnimGraphNode_LinkedInputPose;
|
|
class UAnimGraphNode_LinkedAnimGraphBase;
|
|
class UAnimGraphNode_LinkedAnimGraph;
|
|
class UAnimGraphNode_Root;
|
|
|
|
class FStructProperty;
|
|
class UBlueprintGeneratedClass;
|
|
struct FPoseLinkMappingRecord;
|
|
struct FAnimGraphNodePropertyBinding;
|
|
class FAnimBlueprintCompilerContext;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// FAnimBlueprintCompilerContext
|
|
class FAnimBlueprintCompilerContext : public FKismetCompilerContext
|
|
{
|
|
friend class FAnimBlueprintCompilerCreationContext;
|
|
friend class FAnimBlueprintCompilationContext;
|
|
friend class FAnimBlueprintVariableCreationContext;
|
|
friend class FAnimBlueprintCompilationBracketContext;
|
|
friend class FAnimBlueprintPostExpansionStepContext;
|
|
friend class FAnimBlueprintCopyTermDefaultsContext;
|
|
|
|
protected:
|
|
typedef FKismetCompilerContext Super;
|
|
public:
|
|
FAnimBlueprintCompilerContext(UAnimBlueprint* SourceSketch, FCompilerResultsLog& InMessageLog, const FKismetCompilerOptions& InCompileOptions);
|
|
virtual ~FAnimBlueprintCompilerContext();
|
|
|
|
protected:
|
|
// Implementation of FKismetCompilerContext interface
|
|
virtual void CreateClassVariablesFromBlueprint() override;
|
|
virtual UEdGraphSchema_K2* CreateSchema() override;
|
|
virtual void MergeUbergraphPagesIn(UEdGraph* Ubergraph) override;
|
|
virtual void ProcessOneFunctionGraph(UEdGraph* SourceGraph, bool bInternalFunction = false) override;
|
|
virtual void SpawnNewClass(const FString& NewClassName) override;
|
|
virtual void OnNewClassSet(UBlueprintGeneratedClass* ClassToUse) override;
|
|
virtual void OnPostCDOCompiled() override;
|
|
virtual void CopyTermDefaultsToDefaultObject(UObject* DefaultObject) override;
|
|
virtual void PostCompile() override;
|
|
virtual void PostCompileDiagnostics() override;
|
|
virtual void EnsureProperGeneratedClass(UClass*& TargetClass) override;
|
|
virtual void CleanAndSanitizeClass(UBlueprintGeneratedClass* ClassToClean, UObject*& InOldCDO) override;
|
|
virtual void FinishCompilingClass(UClass* Class) override;
|
|
virtual void PrecompileFunction(FKismetFunctionContext& Context, EInternalCompilerFlags InternalFlags) override;
|
|
virtual void SetCalculatedMetaDataAndFlags(UFunction* Function, UK2Node_FunctionEntry* EntryNode, const UEdGraphSchema_K2* Schema ) override;
|
|
virtual bool ShouldForceKeepNode(const UEdGraphNode* Node) const override;
|
|
virtual void PostExpansionStep(const UEdGraph* Graph) override;
|
|
// End of FKismetCompilerContext interface
|
|
|
|
protected:
|
|
typedef TArray<UEdGraphPin*> UEdGraphPinArray;
|
|
|
|
protected:
|
|
UScriptStruct* NewAnimBlueprintConstants;
|
|
UScriptStruct* NewAnimBlueprintMutables;
|
|
FStructProperty* NewMutablesProperty;
|
|
UAnimBlueprint* AnimBlueprint;
|
|
|
|
UAnimationGraphSchema* AnimSchema;
|
|
|
|
// Map of allocated v3 nodes that are members of the class
|
|
TMap<class UAnimGraphNode_Base*, FProperty*> AllocatedAnimNodes;
|
|
TMap<FProperty*, class UAnimGraphNode_Base*> AllocatedNodePropertiesToNodes;
|
|
TMap<FProperty*, class UAnimGraphNode_Base*> AllocatedNodeConstantPropertiesToNodes;
|
|
TMap<int32, FProperty*> AllocatedPropertiesByIndex;
|
|
|
|
// Map of true source objects (user edited ones) to the cloned ones that are actually compiled
|
|
TMap<class UAnimGraphNode_Base*, UAnimGraphNode_Base*> SourceNodeToProcessedNodeMap;
|
|
|
|
// Index of the nodes (must match up with the runtime discovery process of nodes, which runs thru the property chain)
|
|
int32 AllocateNodeIndexCounter;
|
|
TMap<class UAnimGraphNode_Base*, int32> AllocatedAnimNodeIndices;
|
|
|
|
// Map from pose link LinkID address
|
|
//@TODO: Bad structure for a list of these
|
|
TArray<FPoseLinkMappingRecord> ValidPoseLinkList;
|
|
|
|
// Stub graphs we generated for animation graph functions
|
|
TArray<UEdGraph*> GeneratedStubGraphs;
|
|
|
|
// True if any parent class is also generated from an animation blueprint
|
|
bool bIsDerivedAnimBlueprint;
|
|
|
|
// Graph schema classes that this compiler is aware of - they will skip default function processing
|
|
TArray<TSubclassOf<UEdGraphSchema>> KnownGraphSchemas;
|
|
|
|
// Expose compile options to handlers
|
|
using FKismetCompilerContext::CompileOptions;
|
|
|
|
// Records of folded properties gleaned from nodes
|
|
TArray<TSharedRef<IAnimBlueprintCompilationContext::FFoldedPropertyRecord>> ConstantPropertyRecords;
|
|
TArray<TSharedRef<IAnimBlueprintCompilationContext::FFoldedPropertyRecord>> MutablePropertyRecords;
|
|
|
|
// Allows lookups to see if a node participates in constant folding
|
|
TMap<UAnimGraphNode_Base*, TArray<TSharedRef<IAnimBlueprintCompilationContext::FFoldedPropertyRecord>>> NodeToFoldedPropertyRecordMap;
|
|
|
|
// Maps of extension <-> generated property on the instance
|
|
TMap<UAnimBlueprintExtension*, FStructProperty*> ExtensionToInstancePropertyMap;
|
|
TMap<FStructProperty*, UAnimBlueprintExtension*> InstancePropertyToExtensionMap;
|
|
|
|
// Maps of extension <-> generated property on the class
|
|
TMap<UAnimBlueprintExtension*, FStructProperty*> ExtensionToClassPropertyMap;
|
|
TMap<FStructProperty*, UAnimBlueprintExtension*> ClassPropertyToExtensionMap;
|
|
|
|
private:
|
|
// Get the generated class as an anim blueprint generated class
|
|
UAnimBlueprintGeneratedClass* GetNewAnimBlueprintClass() const { return CastChecked<UAnimBlueprintGeneratedClass>(NewClass); };
|
|
|
|
// Run a function on the passed-in graph and each subgraph of it
|
|
void ForAllSubGraphs(UEdGraph* InGraph, TFunctionRef<void(UEdGraph*)> InPerGraphFunction);
|
|
|
|
// Prunes any nodes that aren't reachable via a pose link
|
|
void PruneIsolatedAnimationNodes(const TArray<UAnimGraphNode_Base*>& RootSet, TArray<UAnimGraphNode_Base*>& GraphNodes);
|
|
|
|
// Compiles one animation node
|
|
void ProcessAnimationNode(UAnimGraphNode_Base* VisualAnimNode);
|
|
|
|
// Called during ProcessAnimationNode - gather property folding records for the node
|
|
void GatherFoldRecordsForAnimationNode(const UScriptStruct* InNodeType, FStructProperty* InNodeProperty, UAnimGraphNode_Base* InVisualAnimNode);
|
|
|
|
// Compiles an entire animation graph
|
|
void ProcessAllAnimationNodes();
|
|
|
|
// Processes all the supplied anim nodes
|
|
void ProcessAnimationNodes(TArray<UAnimGraphNode_Base*>& AnimNodeList);
|
|
|
|
// Process all the requested extensions
|
|
void ProcessExtensions();
|
|
|
|
// Gets all anim graph nodes that are piped into the provided node (traverses input pins)
|
|
void GetLinkedAnimNodes(UAnimGraphNode_Base* InGraphNode, TArray<UAnimGraphNode_Base*>& LinkedAnimNodes) const;
|
|
void GetLinkedAnimNodes_TraversePin(UEdGraphPin* InPin, TArray<UAnimGraphNode_Base*>& LinkedAnimNodes) const;
|
|
void GetLinkedAnimNodes_ProcessAnimNode(UAnimGraphNode_Base* AnimNode, TArray<UAnimGraphNode_Base*>& LinkedAnimNodes) const;
|
|
|
|
// Returns the allocation index of the specified node, processing it if it was pending
|
|
int32 GetAllocationIndexOfNode(UAnimGraphNode_Base* VisualAnimNode);
|
|
|
|
// Create transient stub functions for each anim graph we are compiling
|
|
void CreateAnimGraphStubFunctions();
|
|
|
|
// Clean up transient stub functions
|
|
void DestroyAnimGraphStubFunctions();
|
|
|
|
// Expands split pins for a graph
|
|
void ExpandSplitPins(UEdGraph* InGraph);
|
|
|
|
// Add the specified compiled-in attribute uniquely to the specified node
|
|
void AddAttributesToNode(UAnimGraphNode_Base* InNode, TArrayView<const FName> InAttributes) const;
|
|
|
|
// Get the current compiled-in attributes uniquely assigned to the specified node
|
|
TArrayView<const FName> GetAttributesFromNode(UAnimGraphNode_Base* InNode) const;
|
|
|
|
// Called at the start of compilation to (re-) create the mutable struct
|
|
void RecreateMutables();
|
|
|
|
// (Re-)creates sparse class data structure. Called at the start of compilation to (re-) create the internal sparse
|
|
// class data. For derived anim BPs this is called just-in-time before CDO copy. This is to ensure that the sparse
|
|
// class data is always updated, as in some cases as the layout does not change a full compilation of a (data-only)
|
|
// derived anim BP may be skipped.
|
|
void RecreateSparseClassData();
|
|
|
|
// Create a uniquely named variable corresponding to an object in the current class
|
|
FProperty* CreateUniqueVariable(UObject* InForObject, const FEdGraphPinType& Type);
|
|
|
|
/** Creates a variable on the specified struct */
|
|
FProperty* CreateStructVariable(UScriptStruct* InStruct, const FName VarName, const FEdGraphPinType& VarType);
|
|
|
|
/** Adds a record for a potentially-folded anim node property */
|
|
void AddFoldedPropertyRecord(UAnimGraphNode_Base* InAnimGraphNode, FStructProperty* InAnimNodeProperty, FProperty* InProperty, bool bInExposedOnPin, bool bInPinConnected);
|
|
|
|
/** Process any anim node properties that are 'foldable' */
|
|
void ProcessFoldedPropertyRecords();
|
|
|
|
// Check whether an anim node participates in constant folding
|
|
bool IsAnimGraphNodeFolded(UAnimGraphNode_Base* InNode) const;
|
|
|
|
// Copy the AnimNodeData array etc. from root anim BP class to a derived anim BP
|
|
void CopyAnimNodeDataFromRoot() const;
|
|
|
|
// Get the folded property record, if any, for the supplied node & named property
|
|
const IAnimBlueprintCompilationContext::FFoldedPropertyRecord* GetFoldedPropertyRecord(UAnimGraphNode_Base* InNode, FName InPropertyName) const;
|
|
};
|
|
|