2014-12-07 19:09:38 -05:00
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
# include "AnimGraphPrivatePCH.h"
# include "GraphEditorActions.h"
# include "ScopedTransaction.h"
2014-10-02 16:48:56 -04:00
# include "EdGraphUtilities.h"
2014-04-24 14:34:01 -04:00
# include "AnimGraphNode_SaveCachedPose.h"
2014-04-24 08:49:31 -04:00
# include "AnimGraphNode_UseCachedPose.h"
2014-09-29 10:35:16 -04:00
# include "BlueprintNodeSpawner.h"
# include "BlueprintActionDatabaseRegistrar.h"
# include "BlueprintActionFilter.h"
2014-03-14 14:13:41 -04:00
/////////////////////////////////////////////////////
// UAnimGraphNode_UseCachedPose
2014-04-23 18:30:37 -04:00
# define LOCTEXT_NAMESPACE "A3Nodes"
2014-10-14 10:29:11 -04:00
UAnimGraphNode_UseCachedPose : : UAnimGraphNode_UseCachedPose ( const FObjectInitializer & ObjectInitializer )
: Super ( ObjectInitializer )
2014-03-14 14:13:41 -04:00
{
}
2014-12-16 17:44:46 -05:00
void UAnimGraphNode_UseCachedPose : : EarlyValidation ( class FCompilerResultsLog & MessageLog ) const
2014-09-29 10:35:16 -04:00
{
2014-12-16 17:44:46 -05:00
Super : : EarlyValidation ( MessageLog ) ;
2014-10-02 16:48:56 -04:00
bool bRefreshSavCachedPoseNode = true ;
2014-09-29 10:35:16 -04:00
2014-10-02 16:48:56 -04:00
// Check to see the current cached node is still valid (and not deleted, by checking pin connections)
if ( SaveCachedPoseNode . IsValid ( ) )
2014-09-29 10:35:16 -04:00
{
2014-10-02 16:48:56 -04:00
// The node has a single pin, make sure it's there
check ( SaveCachedPoseNode - > Pins . Num ( ) ) ;
2014-09-29 10:35:16 -04:00
2014-10-02 16:48:56 -04:00
// Deleted nodes have no links, otherwise we will be doing some wasted work on unlinked nodes
if ( SaveCachedPoseNode - > Pins [ 0 ] - > LinkedTo . Num ( ) )
{
// The node has links, it's valid, continue to use it
bRefreshSavCachedPoseNode = false ;
}
}
// We need to refresh the cached pose node this node is linked to
if ( bRefreshSavCachedPoseNode & & ! NameOfCache . IsEmpty ( ) )
{
UBlueprint * GraphBlueprint = FBlueprintEditorUtils : : FindBlueprintForGraph ( GetGraph ( ) ) ;
check ( GraphBlueprint ) ;
TArray < UEdGraph * > AllGraphs ;
GraphBlueprint - > GetAllGraphs ( AllGraphs ) ;
for ( UEdGraph * Graph : AllGraphs )
2014-09-29 10:35:16 -04:00
{
// Get a list of all save cached pose nodes
TArray < UAnimGraphNode_SaveCachedPose * > CachedPoseNodes ;
Graph - > GetNodesOfClass ( CachedPoseNodes ) ;
// Go through all the nodes and find one with a title that matches ours
for ( auto NodeIt = CachedPoseNodes . CreateIterator ( ) ; NodeIt ; + + NodeIt )
{
if ( ( * NodeIt ) - > CacheName = = NameOfCache )
{
2014-10-02 16:48:56 -04:00
// Fix the original Blueprint node as well as the compiled version
MessageLog . FindSourceObjectTypeChecked < UAnimGraphNode_UseCachedPose > ( this ) - > SaveCachedPoseNode = * NodeIt ;
2014-09-29 10:35:16 -04:00
SaveCachedPoseNode = * NodeIt ;
break ;
}
}
}
}
}
2014-09-03 18:14:09 -04:00
FText UAnimGraphNode_UseCachedPose : : GetTooltipText ( ) const
2014-03-14 14:13:41 -04:00
{
2014-09-03 18:14:09 -04:00
return LOCTEXT ( " AnimGraphNode_UseCachedPose_Tooltip " , " References an animation tree elsewhere in the blueprint, which will be evaluated at most once per frame. " ) ;
2014-03-14 14:13:41 -04:00
}
2014-04-23 18:30:37 -04:00
FText UAnimGraphNode_UseCachedPose : : GetNodeTitle ( ENodeTitleType : : Type TitleType ) const
2014-03-14 14:13:41 -04:00
{
2014-09-29 10:35:16 -04:00
FFormatNamedArguments Args ;
if ( SaveCachedPoseNode . IsValid ( ) )
2014-09-04 11:25:05 -04:00
{
2014-09-29 10:35:16 -04:00
NameOfCache = SaveCachedPoseNode - > CacheName ;
2014-09-04 11:25:05 -04:00
}
2014-09-29 10:35:16 -04:00
Args . Add ( TEXT ( " CachePoseName " ) , FText : : FromString ( NameOfCache ) ) ;
return FText : : Format ( LOCTEXT ( " AnimGraphNode_UseCachedPose_Title " , " Use cached pose '{CachePoseName}' " ) , Args ) ;
2014-04-23 18:30:37 -04:00
}
2014-03-14 14:13:41 -04:00
FString UAnimGraphNode_UseCachedPose : : GetNodeCategory ( ) const
{
return TEXT ( " Cached Poses " ) ;
}
2014-09-29 10:35:16 -04:00
void UAnimGraphNode_UseCachedPose : : GetMenuActions ( FBlueprintActionDatabaseRegistrar & ActionRegistrar ) const
{
auto PostSpawnSetupLambda = [ ] ( UEdGraphNode * NewNode , bool bIsTemplateNode , FString CacheNodeName , UAnimGraphNode_SaveCachedPose * SaveCachePoseNode )
{
UAnimGraphNode_UseCachedPose * UseCachedPose = CastChecked < UAnimGraphNode_UseCachedPose > ( NewNode ) ;
// we use an empty CacheName in GetNodeTitle() to relay the proper menu title
UseCachedPose - > SaveCachedPoseNode = SaveCachePoseNode ;
} ;
UObject const * ActionKey = ActionRegistrar . GetActionKeyFilter ( ) ;
if ( UBlueprint const * Blueprint = Cast < UBlueprint > ( ActionKey ) )
{
// Get a list of all save cached pose nodes
TArray < UAnimGraphNode_SaveCachedPose * > CachedPoseNodes ;
FBlueprintEditorUtils : : GetAllNodesOfClass < UAnimGraphNode_SaveCachedPose > ( Blueprint , /*out*/ CachedPoseNodes ) ;
// Offer a use node for each of them
for ( auto NodeIt = CachedPoseNodes . CreateIterator ( ) ; NodeIt ; + + NodeIt )
{
UBlueprintNodeSpawner * NodeSpawner = UBlueprintNodeSpawner : : Create ( GetClass ( ) ) ;
NodeSpawner - > CustomizeNodeDelegate = UBlueprintNodeSpawner : : FCustomizeNodeDelegate : : CreateStatic ( PostSpawnSetupLambda , ( * NodeIt ) - > CacheName , * NodeIt ) ;
ActionRegistrar . AddBlueprintAction ( ActionKey , NodeSpawner ) ;
}
}
}
bool UAnimGraphNode_UseCachedPose : : IsActionFilteredOut ( class FBlueprintActionFilter const & Filter )
{
bool bIsFilteredOut = false ;
if ( SaveCachedPoseNode . IsValid ( ) )
{
FBlueprintActionContext const & FilterContext = Filter . Context ;
for ( UBlueprint * Blueprint : FilterContext . Blueprints )
{
if ( SaveCachedPoseNode - > GetBlueprint ( ) ! = Blueprint )
{
bIsFilteredOut = true ;
break ;
}
}
}
return bIsFilteredOut ;
}
2014-04-23 18:30:37 -04:00
# undef LOCTEXT_NAMESPACE