123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- // Copyright 2022 Tracer Interactive, LLC. All Rights Reserved.
- #include "K2Node_JsonLibraryFromStruct.h"
- #include "Engine/UserDefinedStruct.h"
- #include "EdGraph/EdGraphPin.h"
- #include "EdGraphSchema_K2.h"
- #include "K2Node_CallFunction.h"
- #include "K2Node_IfThenElse.h"
- #include "Kismet2/BlueprintEditorUtils.h"
- #include "KismetCompiler.h"
- #include "BlueprintActionDatabaseRegistrar.h"
- #include "BlueprintNodeSpawner.h"
- #include "EditorCategoryUtils.h"
- #include "JsonLibraryObject.h"
- #include "JsonLibraryBlueprintHelpers.h"
- #define LOCTEXT_NAMESPACE "K2Node_JsonLibraryFromStruct"
- struct UK2Node_JsonLibraryFromStructHelper
- {
- static FName DataPinName;
- static FName FailedPinName;
- };
- FName UK2Node_JsonLibraryFromStructHelper::FailedPinName( *LOCTEXT( "FailedPinName", "Failed" ).ToString() );
- FName UK2Node_JsonLibraryFromStructHelper::DataPinName( *LOCTEXT( "DataPinName", "Structure" ).ToString() );
- UK2Node_JsonLibraryFromStruct::UK2Node_JsonLibraryFromStruct( const FObjectInitializer& ObjectInitializer )
- : Super( ObjectInitializer )
- {
- NodeTooltip = LOCTEXT( "NodeTooltip", "Attempts to parse a JSON object into a structure." );
- }
- void UK2Node_JsonLibraryFromStruct::AllocateDefaultPins()
- {
- const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
- CreatePin( EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute );
- UEdGraphPin* SuccessPin = CreatePin( EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then );
- SuccessPin->PinFriendlyName = LOCTEXT( "JsonLibraryFromStruct Success Exec pin", "Success" );
- UEdGraphPin* FailedPin = CreatePin( EGPD_Output, UEdGraphSchema_K2::PC_Exec, UK2Node_JsonLibraryFromStructHelper::FailedPinName );
- FailedPin->PinFriendlyName = LOCTEXT( "JsonLibraryFromStruct Failed Exec pin", "Failure" );
- UEdGraphPin* DataPin = CreatePin( EGPD_Input, UEdGraphSchema_K2::PC_Wildcard, UK2Node_JsonLibraryFromStructHelper::DataPinName );
- DataPin->bDisplayAsMutableRef = true;
- SetPinToolTip( *DataPin, LOCTEXT( "DataPinDescription", "The structure to convert." ) );
- UScriptStruct* JsonObjectStruct = TBaseStructure<FJsonLibraryObject>::Get();
- UEdGraphPin* ResultPin = CreatePin( EGPD_Output, UEdGraphSchema_K2::PC_Struct, JsonObjectStruct, UEdGraphSchema_K2::PN_ReturnValue );
- ResultPin->PinFriendlyName = LOCTEXT( "JsonLibraryFromStruct Out Json", "Object" );
- SetPinToolTip( *ResultPin, LOCTEXT( "ResultPinDescription", "The returned JSON object, if converted." ) );
- Super::AllocateDefaultPins();
- }
- void UK2Node_JsonLibraryFromStruct::SetPinToolTip( UEdGraphPin& MutatablePin, const FText& PinDescription ) const
- {
- MutatablePin.PinToolTip = UEdGraphSchema_K2::TypeToText( MutatablePin.PinType ).ToString();
- UEdGraphSchema_K2 const* const K2Schema = Cast<const UEdGraphSchema_K2>( GetSchema() );
- if ( K2Schema )
- {
- MutatablePin.PinToolTip += TEXT( " " );
- MutatablePin.PinToolTip += K2Schema->GetPinDisplayName( &MutatablePin ).ToString();
- }
- MutatablePin.PinToolTip += FString( TEXT( "\n" ) ) + PinDescription.ToString();
- }
- void UK2Node_JsonLibraryFromStruct::RefreshInputPinType()
- {
- UEdGraphPin* DataPin = GetDataPin();
- const bool bFillTypeFromConnected = DataPin && ( DataPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Wildcard );
- UScriptStruct* InputType = nullptr;
- if ( bFillTypeFromConnected )
- {
- FEdGraphPinType PinType = DataPin->PinType;
- if ( DataPin->LinkedTo.Num() > 0 )
- PinType = DataPin->LinkedTo[ 0 ]->PinType;
- if ( PinType.PinCategory == UEdGraphSchema_K2::PC_Struct )
- InputType = Cast<UScriptStruct>( PinType.PinSubCategoryObject.Get() );
- }
- SetPropertyTypeForStruct( InputType );
- }
- void UK2Node_JsonLibraryFromStruct::SetPropertyTypeForStruct( UScriptStruct* StructType )
- {
- if ( StructType == GetPropertyTypeForStruct() )
- return;
- UEdGraphPin* DataPin = GetDataPin();
- if ( DataPin->SubPins.Num() > 0 )
- GetSchema()->RecombinePin( DataPin );
-
- DataPin->PinType.PinSubCategoryObject = StructType;
- DataPin->PinType.PinCategory = StructType ?
- UEdGraphSchema_K2::PC_Struct :
- UEdGraphSchema_K2::PC_Wildcard;
- CachedNodeTitle.Clear();
- }
- UScriptStruct* UK2Node_JsonLibraryFromStruct::GetPropertyTypeForStruct() const
- {
- UScriptStruct* DataStructType = (UScriptStruct*)( GetDataPin()->PinType.PinSubCategoryObject.Get() );
- return DataStructType;
- }
- void UK2Node_JsonLibraryFromStruct::GetMenuActions( FBlueprintActionDatabaseRegistrar& ActionRegistrar ) const
- {
- UClass* ActionKey = GetClass();
- if ( ActionRegistrar.IsOpenForRegistration( ActionKey ) )
- {
- UBlueprintNodeSpawner* NodeSpawner = UBlueprintNodeSpawner::Create( GetClass() );
- check( NodeSpawner != nullptr );
- ActionRegistrar.AddBlueprintAction( ActionKey, NodeSpawner );
- }
- }
- FText UK2Node_JsonLibraryFromStruct::GetMenuCategory() const
- {
- return FText::FromString( TEXT( "JSON Library|Structure" ) );
- }
- bool UK2Node_JsonLibraryFromStruct::IsConnectionDisallowed( const UEdGraphPin* MyPin, const UEdGraphPin* OtherPin, FString& OutReason ) const
- {
- if ( MyPin == GetDataPin() && MyPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Wildcard )
- {
- bool bDisallowed = true;
- if ( OtherPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Struct )
- {
- if ( UScriptStruct* ConnectionType = Cast<UScriptStruct>( OtherPin->PinType.PinSubCategoryObject.Get() ) )
- bDisallowed = false;
- }
- else if ( OtherPin->PinType.PinCategory == UEdGraphSchema_K2::PC_Wildcard )
- bDisallowed = false;
- if ( bDisallowed )
- OutReason = TEXT( "Must be a structure." );
- return bDisallowed;
- }
- return false;
- }
- FText UK2Node_JsonLibraryFromStruct::GetTooltipText() const
- {
- return NodeTooltip;
- }
- UEdGraphPin* UK2Node_JsonLibraryFromStruct::GetThenPin()const
- {
- const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
- UEdGraphPin* Pin = FindPinChecked( UEdGraphSchema_K2::PN_Then );
- check( Pin->Direction == EGPD_Output );
- return Pin;
- }
- UEdGraphPin* UK2Node_JsonLibraryFromStruct::GetDataPin() const
- {
- UEdGraphPin* Pin = FindPinChecked( UK2Node_JsonLibraryFromStructHelper::DataPinName );
- check( Pin->Direction == EGPD_Input );
- return Pin;
- }
- UEdGraphPin* UK2Node_JsonLibraryFromStruct::GetFailedPin() const
- {
- UEdGraphPin* Pin = FindPinChecked( UK2Node_JsonLibraryFromStructHelper::FailedPinName );
- check( Pin->Direction == EGPD_Output );
- return Pin;
- }
- UEdGraphPin* UK2Node_JsonLibraryFromStruct::GetResultPin() const
- {
- const UEdGraphSchema_K2* K2Schema = GetDefault<UEdGraphSchema_K2>();
- UEdGraphPin* Pin = FindPinChecked( UEdGraphSchema_K2::PN_ReturnValue );
- check( Pin->Direction == EGPD_Output );
- return Pin;
- }
- FText UK2Node_JsonLibraryFromStruct::GetNodeTitle( ENodeTitleType::Type TitleType ) const
- {
- if ( TitleType == ENodeTitleType::MenuTitle )
- return LOCTEXT( "ListViewTitle", "Structure to JSON" );
-
- if ( UEdGraphPin* DataPin = GetDataPin() )
- {
- UScriptStruct* StructType = GetPropertyTypeForStruct();
- if ( !StructType || DataPin->LinkedTo.Num() == 0 )
- return NSLOCTEXT( "K2Node", "JsonFromStruct_Title_None", "Structure to JSON" );
- if ( CachedNodeTitle.IsOutOfDate( this ) )
- {
- FFormatNamedArguments Args;
- Args.Add( TEXT( "StructName" ), FText::FromName( StructType->GetFName() ) );
-
- FText LocFormat = NSLOCTEXT( "K2Node", "JsonFromStruct", "{StructName} to JSON" );
- CachedNodeTitle.SetCachedText( FText::Format( LocFormat, Args ), this );
- }
- }
- else
- return NSLOCTEXT( "K2Node", "JsonFromStruct_Title_None", "Structure to JSON" );
-
- return CachedNodeTitle;
- }
- void UK2Node_JsonLibraryFromStruct::ExpandNode( FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph )
- {
- Super::ExpandNode( CompilerContext, SourceGraph );
-
- const FName StructToJsonFunctionName = GET_FUNCTION_NAME_CHECKED( UJsonLibraryBlueprintHelpers, StructToJson );
- UK2Node_CallFunction* CallStructToJsonFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>( this, SourceGraph );
- CallStructToJsonFunction->FunctionReference.SetExternalMember( StructToJsonFunctionName, UJsonLibraryBlueprintHelpers::StaticClass() );
- CallStructToJsonFunction->AllocateDefaultPins();
- CompilerContext.MovePinLinksToIntermediate( *GetExecPin(), *( CallStructToJsonFunction->GetExecPin() ) );
-
- UScriptStruct* StructType = GetPropertyTypeForStruct();
- UUserDefinedStruct* UserStructType = Cast<UUserDefinedStruct>( StructType );
-
- UEdGraphPin* StructTypePin = CallStructToJsonFunction->FindPinChecked( TEXT( "StructType" ) );
- if ( UserStructType && UserStructType->PrimaryStruct.IsValid() )
- StructTypePin->DefaultObject = UserStructType->PrimaryStruct.Get();
- else
- StructTypePin->DefaultObject = StructType;
- UEdGraphPin* OriginalDataPin = GetDataPin();
- UEdGraphPin* StructInPin = CallStructToJsonFunction->FindPinChecked( TEXT( "Struct" ) );
- StructInPin->PinType = OriginalDataPin->PinType;
- StructInPin->PinType.PinSubCategoryObject = OriginalDataPin->PinType.PinSubCategoryObject;
- CompilerContext.MovePinLinksToIntermediate( *OriginalDataPin, *StructInPin );
- UEdGraphPin* OriginalReturnPin = FindPinChecked( UEdGraphSchema_K2::PN_ReturnValue );
- UEdGraphPin* FunctionReturnPin = CallStructToJsonFunction->FindPinChecked( UEdGraphSchema_K2::PN_ReturnValue );
- UEdGraphPin* FunctionThenPin = CallStructToJsonFunction->GetThenPin();
- const FName IsValidObjectFunctionName = GET_FUNCTION_NAME_CHECKED( UJsonLibraryBlueprintHelpers, IsValidObject );
- UK2Node_CallFunction* CallIsValidObjectFunction = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>( this, SourceGraph );
- CallIsValidObjectFunction->FunctionReference.SetExternalMember( IsValidObjectFunctionName, UJsonLibraryBlueprintHelpers::StaticClass() );
- CallIsValidObjectFunction->bIsPureFunc = true;
- CallIsValidObjectFunction->AllocateDefaultPins();
- UEdGraphPin* ObjectInPin = CallIsValidObjectFunction->FindPinChecked( TEXT( "Object" ) );
- UEdGraphPin* CallReturnPin = CallIsValidObjectFunction->FindPinChecked( UEdGraphSchema_K2::PN_ReturnValue );
- FunctionReturnPin->MakeLinkTo( ObjectInPin );
- UK2Node_IfThenElse* BranchNode = CompilerContext.SpawnIntermediateNode<UK2Node_IfThenElse>( this, SourceGraph );
- BranchNode->AllocateDefaultPins();
- FunctionThenPin->MakeLinkTo( BranchNode->GetExecPin() );
- CallReturnPin->MakeLinkTo( BranchNode->GetConditionPin() );
- CompilerContext.MovePinLinksToIntermediate( *GetThenPin(), *( BranchNode->GetThenPin() ) );
- CompilerContext.MovePinLinksToIntermediate( *GetFailedPin(), *( BranchNode->GetElsePin() ) );
- CompilerContext.MovePinLinksToIntermediate( *OriginalReturnPin, *FunctionReturnPin );
- BreakAllNodeLinks();
- }
- FSlateIcon UK2Node_JsonLibraryFromStruct::GetIconAndTint( FLinearColor& OutColor ) const
- {
- OutColor = GetNodeTitleColor();
- static FSlateIcon Icon( "EditorStyle", "Kismet.AllClasses.FunctionIcon" );
- return Icon;
- }
- void UK2Node_JsonLibraryFromStruct::PostReconstructNode()
- {
- Super::PostReconstructNode();
- RefreshInputPinType();
- }
- void UK2Node_JsonLibraryFromStruct::EarlyValidation( FCompilerResultsLog& MessageLog ) const
- {
- Super::EarlyValidation( MessageLog );
- if ( UEdGraphPin* DataPin = GetDataPin() )
- {
- if ( DataPin->LinkedTo.Num() == 0 )
- {
- MessageLog.Error( *LOCTEXT( "MissingPins", "Missing pins in @@" ).ToString(), this );
- return;
- }
- }
- }
- void UK2Node_JsonLibraryFromStruct::NotifyPinConnectionListChanged( UEdGraphPin* Pin )
- {
- Super::NotifyPinConnectionListChanged( Pin );
- if ( Pin == GetDataPin() )
- RefreshInputPinType();
- }
- #undef LOCTEXT_NAMESPACE
|