void UK2Node::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) { AllocateDefaultPins(); for (auto OldPin : OldPins) { if (OldPin->ParentPin) { // find the new pin that corresponds to parent, and split it if it isn't already split for (auto NewPin : Pins) { if (FCString::Stricmp(*(NewPin->PinName), *(OldPin->ParentPin->PinName)) == 0) { // Make sure we're not dealing with a menu node UEdGraph* OuterGraph = GetGraph(); if (OuterGraph && OuterGraph->Schema && NewPin->SubPins.Num() == 0) { NewPin->PinType = OldPin->ParentPin->PinType; GetSchema()->SplitPin(NewPin); } } } } } }
void USoundCueGraphNode_Base::ReconstructNode() { // Break any links to 'orphan' pins for (int32 PinIndex = 0; PinIndex < Pins.Num(); ++PinIndex) { UEdGraphPin* Pin = Pins[PinIndex]; TArray<class UEdGraphPin*>& LinkedToRef = Pin->LinkedTo; for (int32 LinkIdx=0; LinkIdx < LinkedToRef.Num(); LinkIdx++) { UEdGraphPin* OtherPin = LinkedToRef[LinkIdx]; // If we are linked to a pin that its owner doesn't know about, break that link if (!OtherPin->GetOwningNode()->Pins.Contains(OtherPin)) { Pin->LinkedTo.Remove(OtherPin); } } } // Store the old Input and Output pins TArray<UEdGraphPin*> OldInputPins; GetInputPins(OldInputPins); UEdGraphPin* OldOutputPin = GetOutputPin(); // Move the existing pins to a saved array TArray<UEdGraphPin*> OldPins(Pins); Pins.Empty(); // Recreate the new pins AllocateDefaultPins(); // Get new Input and Output pins TArray<UEdGraphPin*> NewInputPins; GetInputPins(NewInputPins); UEdGraphPin* NewOutputPin = GetOutputPin(); for (int32 PinIndex = 0; PinIndex < OldInputPins.Num(); PinIndex++) { if (PinIndex < NewInputPins.Num()) { NewInputPins[PinIndex]->CopyPersistentDataFromOldPin(*OldInputPins[PinIndex]); } } NewOutputPin->CopyPersistentDataFromOldPin(*OldOutputPin); OldInputPins.Empty(); OldOutputPin = NULL; // Throw away the original pins for (int32 OldPinIndex = 0; OldPinIndex < OldPins.Num(); ++OldPinIndex) { UEdGraphPin* OldPin = OldPins[OldPinIndex]; OldPin->Modify(); OldPin->BreakAllPinLinks(); UEdGraphNode::DestroyPin(OldPin); } OldPins.Empty(); }
void UK2Node_LatentAbilityCall::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) { AllocateDefaultPins(); UClass* UseSpawnClass = GetClassToSpawn(&OldPins); if (UseSpawnClass != NULL) { CreatePinsForClass(UseSpawnClass); } }
void UK2Node_SpawnActorFromClass::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) { AllocateDefaultPins(); UClass* UseSpawnClass = GetClassToSpawn(&OldPins); if( UseSpawnClass != NULL ) { TArray<UEdGraphPin*> ClassPins; CreatePinsForClass(UseSpawnClass, ClassPins); } }
void UK2Node_SpawnActor::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) { AllocateDefaultPins(); UClass* UseSpawnClass = GetClassToSpawn(&OldPins); if( UseSpawnClass != NULL ) { CreatePinsForClass(UseSpawnClass); } RestoreSplitPins(OldPins); }
void UEdGraphNode_Reference::SetReferenceNodeCollapsed(const FIntPoint& NodeLoc, int32 InNumReferencesExceedingMax) { NodePosX = NodeLoc.X; NodePosY = NodeLoc.Y; PackageNames.Empty(); NodeComment = FText::Format(LOCTEXT("ReferenceNodeCollapsedMessage", "{0} other nodes"), FText::AsNumber(InNumReferencesExceedingMax)).ToString(); NodeTitle = LOCTEXT("ReferenceNodeCollapsedTitle", "Collapsed nodes"); CacheAssetData(FAssetData()); AllocateDefaultPins(); }
void UK2Node_GetClassDefaults::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) { AllocateDefaultPins(); // Recreate output pins based on the previous input class UEdGraphPin* OldClassPin = FindClassPin(OldPins); if(UClass* InputClass = GetInputClass(OldClassPin)) { CreateOutputPins(InputClass); } RestoreSplitPins(OldPins); }
void UMaterialGraphNode::RecreateAndLinkNode() { // Throw away the original pins for (int32 PinIndex = 0; PinIndex < Pins.Num(); ++PinIndex) { UEdGraphPin* Pin = Pins[PinIndex]; Pin->Modify(); Pin->BreakAllPinLinks(); #if 0 UEdGraphNode::ReturnPinToPool(Pin); #else Pin->Rename(NULL, GetTransientPackage(), REN_None); Pin->RemoveFromRoot(); Pin->MarkPendingKill(); #endif } Pins.Empty(); AllocateDefaultPins(); CastChecked<UMaterialGraph>(GetGraph())->LinkGraphNodesFromMaterial(); }
void UEdGraphNode_Reference::SetupReferenceNode(const FIntPoint& NodeLoc, const TArray<FName>& NewPackageNames, const FAssetData& InAssetData) { check(NewPackageNames.Num() > 0); NodePosX = NodeLoc.X; NodePosY = NodeLoc.Y; PackageNames = NewPackageNames; FString ShortPackageName = FPackageName::GetLongPackageAssetName(NewPackageNames[0].ToString()); if ( NewPackageNames.Num() == 1 ) { NodeComment = NewPackageNames[0].ToString(); NodeTitle = FText::FromString(ShortPackageName); } else { NodeComment = FText::Format(LOCTEXT("ReferenceNodeMultiplePackagesTitle", "{0} nodes"), FText::AsNumber(NewPackageNames.Num())).ToString(); NodeTitle = FText::Format(LOCTEXT("ReferenceNodeMultiplePackagesComment", "{0} and {1} others"), FText::FromString(ShortPackageName), FText::AsNumber(NewPackageNames.Num())); } CacheAssetData(InAssetData); AllocateDefaultPins(); }
void UK2Node_VariableSetRef::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& OldPins) { AllocateDefaultPins(); // Coerce the type of the node from the old pin, if available UEdGraphPin* OldTargetPin = NULL; for( auto OldPinIt = OldPins.CreateIterator(); OldPinIt; ++OldPinIt ) { UEdGraphPin* CurrPin = *OldPinIt; if( CurrPin->PinName == TargetVarPinName ) { OldTargetPin = CurrPin; break; } } if( OldTargetPin ) { UEdGraphPin* NewTargetPin = GetTargetPin(); CoerceTypeFromPin(OldTargetPin); } CachedNodeTitle.MarkDirty(); }
void UNiagaraNodeOutput::ReallocatePins() { Modify(); // Break any links to 'orphan' pins for (int32 PinIndex = 0; PinIndex < Pins.Num(); ++PinIndex) { UEdGraphPin* Pin = Pins[PinIndex]; TArray<class UEdGraphPin*>& LinkedToRef = Pin->LinkedTo; for (int32 LinkIdx = 0; LinkIdx < LinkedToRef.Num(); LinkIdx++) { UEdGraphPin* OtherPin = LinkedToRef[LinkIdx]; // If we are linked to a pin that its owner doesn't know about, break that link if (!OtherPin->GetOwningNode()->Pins.Contains(OtherPin)) { Pin->LinkedTo.Remove(OtherPin); } } } // Store the old Input and Output pins TArray<UEdGraphPin*> OldInputPins; TArray<UEdGraphPin*> OldOutputPins; GetInputPins(OldInputPins); GetOutputPins(OldOutputPins); // Move the existing pins to a saved array TArray<UEdGraphPin*> OldPins(Pins); Pins.Empty(); // Recreate the new pins AllocateDefaultPins(); // Get new Input and Output pins TArray<UEdGraphPin*> NewInputPins; TArray<UEdGraphPin*> NewOutputPins; GetInputPins(NewInputPins); GetOutputPins(NewOutputPins); for (int32 PinIndex = 0; PinIndex < OldInputPins.Num(); PinIndex++) { if (PinIndex < NewInputPins.Num()) { NewInputPins[PinIndex]->CopyPersistentDataFromOldPin(*OldInputPins[PinIndex]); } } for (int32 PinIndex = 0; PinIndex < OldOutputPins.Num(); PinIndex++) { if (PinIndex < NewOutputPins.Num()) { NewOutputPins[PinIndex]->CopyPersistentDataFromOldPin(*OldOutputPins[PinIndex]); } } OldInputPins.Empty(); OldOutputPins.Empty(); // Throw away the original pins for (int32 OldPinIndex = 0; OldPinIndex < OldPins.Num(); ++OldPinIndex) { UEdGraphPin* OldPin = OldPins[OldPinIndex]; OldPin->Modify(); OldPin->BreakAllPinLinks(); #if 0 UEdGraphNode::ReturnPinToPool(OldPin); #else OldPin->Rename(NULL, GetTransientPackage(), REN_None); OldPin->RemoveFromRoot(); OldPin->MarkPendingKill(); #endif } OldPins.Empty(); GetGraph()->NotifyGraphChanged(); }
void UK2Node_LoadAsset::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) { Super::ExpandNode(CompilerContext, SourceGraph); const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema(); check(Schema); bool bIsErrorFree = true; // Create LoadAsset function call auto CallLoadAssetNode = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph); CallLoadAssetNode->FunctionReference.SetExternalMember(NativeFunctionName(), UKismetSystemLibrary::StaticClass()); CallLoadAssetNode->AllocateDefaultPins(); // connect to input exe { auto InputExePin = GetExecPin(); auto CallFunctionInputExePin = CallLoadAssetNode->GetExecPin(); bIsErrorFree &= InputExePin && CallFunctionInputExePin && CompilerContext.MovePinLinksToIntermediate(*InputExePin, *CallFunctionInputExePin).CanSafeConnect(); } // Create Local Variable UK2Node_TemporaryVariable* TempVarOutput = CompilerContext.SpawnInternalVariable(this, GetOutputCategory(), FString(), UObject::StaticClass(), false); // Create assign node auto AssignNode = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(this, SourceGraph); AssignNode->AllocateDefaultPins(); auto LoadedObjectVariablePin = TempVarOutput->GetVariablePin(); // connect local variable to assign node { auto AssignLHSPPin = AssignNode->GetVariablePin(); bIsErrorFree &= AssignLHSPPin && LoadedObjectVariablePin && Schema->TryCreateConnection(AssignLHSPPin, LoadedObjectVariablePin); } // connect local variable to output { auto OutputObjectPinPin = FindPin(GetOutputPinName()); bIsErrorFree &= LoadedObjectVariablePin && OutputObjectPinPin && CompilerContext.MovePinLinksToIntermediate(*OutputObjectPinPin, *LoadedObjectVariablePin).CanSafeConnect(); } // connect assign exec input to function output { auto CallFunctionOutputExePin = CallLoadAssetNode->FindPin(Schema->PN_Then); auto AssignInputExePin = AssignNode->GetExecPin(); bIsErrorFree &= AssignInputExePin && CallFunctionOutputExePin && Schema->TryCreateConnection(AssignInputExePin, CallFunctionOutputExePin); } // connect assign exec output to output { auto OutputExePin = FindPin(Schema->PN_Then); auto AssignOutputExePin = AssignNode->GetThenPin(); bIsErrorFree &= OutputExePin && AssignOutputExePin && CompilerContext.MovePinLinksToIntermediate(*OutputExePin, *AssignOutputExePin).CanSafeConnect(); } // connect to asset { auto AssetPin = FindPin(GetInputPinName()); auto CallFunctionAssetPin = CallLoadAssetNode->FindPin(GetInputPinName()); ensure(CallFunctionAssetPin); bIsErrorFree &= AssetPin && CallFunctionAssetPin && CompilerContext.MovePinLinksToIntermediate(*AssetPin, *CallFunctionAssetPin).CanSafeConnect(); } // Create OnLoadEvent const FString DelegateOnLoadedParamName(TEXT("OnLoaded")); auto OnLoadEventNode = CompilerContext.SpawnIntermediateNode<UK2Node_CustomEvent>(this, SourceGraph); OnLoadEventNode->CustomFunctionName = *FString::Printf(TEXT("OnLoaded_%s"), *OnLoadEventNode->NodeGuid.ToString()); OnLoadEventNode->AllocateDefaultPins(); { UFunction* LoadAssetFunction = CallLoadAssetNode->GetTargetFunction(); UDelegateProperty* OnLoadDelegateProperty = LoadAssetFunction ? FindField<UDelegateProperty>(LoadAssetFunction, *DelegateOnLoadedParamName) : nullptr; UFunction* OnLoadedSignature = OnLoadDelegateProperty ? OnLoadDelegateProperty->SignatureFunction : nullptr; ensure(OnLoadedSignature); for (TFieldIterator<UProperty> PropIt(OnLoadedSignature); PropIt && (PropIt->PropertyFlags & CPF_Parm); ++PropIt) { const UProperty* Param = *PropIt; if (!Param->HasAnyPropertyFlags(CPF_OutParm) || Param->HasAnyPropertyFlags(CPF_ReferenceParm)) { FEdGraphPinType PinType; bIsErrorFree &= Schema->ConvertPropertyToPinType(Param, /*out*/ PinType); bIsErrorFree &= (NULL != OnLoadEventNode->CreateUserDefinedPin(Param->GetName(), PinType, EGPD_Output)); } } } // connect delegate { auto CallFunctionDelegatePin = CallLoadAssetNode->FindPin(DelegateOnLoadedParamName); ensure(CallFunctionDelegatePin); auto EventDelegatePin = OnLoadEventNode->FindPin(UK2Node_CustomEvent::DelegateOutputName); bIsErrorFree &= CallFunctionDelegatePin && EventDelegatePin && Schema->TryCreateConnection(CallFunctionDelegatePin, EventDelegatePin); } // connect loaded object from event to assign { auto LoadedAssetEventPin = OnLoadEventNode->FindPin(TEXT("Loaded")); ensure(LoadedAssetEventPin); auto AssignRHSPPin = AssignNode->GetValuePin(); bIsErrorFree &= AssignRHSPPin && LoadedAssetEventPin && Schema->TryCreateConnection(LoadedAssetEventPin, AssignRHSPPin); } if (!bIsErrorFree) { CompilerContext.MessageLog.Error(*LOCTEXT("InternalConnectionError", "K2Node_LoadAsset: Internal connection error. @@").ToString(), this); } BreakAllNodeLinks(); }
void UK2Node_ConvertAsset::ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) { Super::ExpandNode(CompilerContext, SourceGraph); const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema(); UClass* TargetType = GetTargetClass(); if (TargetType && Schema && (2 == Pins.Num())) { const bool bIsAssetClass = IsAssetClassType(); //Create Convert Function auto ConvertToObjectFunc = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(this, SourceGraph); const FName ConvertFunctionName = bIsAssetClass ? GET_FUNCTION_NAME_CHECKED(UKismetSystemLibrary, Conv_AssetClassToClass) : GET_FUNCTION_NAME_CHECKED(UKismetSystemLibrary, Conv_AssetToObject); ConvertToObjectFunc->FunctionReference.SetExternalMember(ConvertFunctionName, UKismetSystemLibrary::StaticClass()); ConvertToObjectFunc->AllocateDefaultPins(); //Connect input to convert auto InputPin = FindPin(UK2Node_ConvertAssetImpl::InputPinName); const FString ConvertInputName = bIsAssetClass ? FString(TEXT("AssetClass")) : FString(TEXT("Asset")); auto ConvertInput = ConvertToObjectFunc->FindPin(ConvertInputName); bool bIsErrorFree = InputPin && ConvertInput && CompilerContext.MovePinLinksToIntermediate(*InputPin, *ConvertInput).CanSafeConnect(); auto ConvertOutput = ConvertToObjectFunc->GetReturnValuePin(); UEdGraphPin* InnerOutput = nullptr; if (UObject::StaticClass() != TargetType) { //Create Cast Node UK2Node_DynamicCast* CastNode = bIsAssetClass ? CompilerContext.SpawnIntermediateNode<UK2Node_ClassDynamicCast>(this, SourceGraph) : CompilerContext.SpawnIntermediateNode<UK2Node_DynamicCast>(this, SourceGraph); CastNode->SetPurity(true); CastNode->TargetType = TargetType; CastNode->AllocateDefaultPins(); // Connect Object/Class to Cast auto CastInput = CastNode->GetCastSourcePin(); bIsErrorFree &= ConvertOutput && CastInput && Schema->TryCreateConnection(ConvertOutput, CastInput); // Connect output to cast InnerOutput = CastNode->GetCastResultPin(); } else { InnerOutput = ConvertOutput; } auto OutputPin = FindPin(UK2Node_ConvertAssetImpl::OutputPinName); bIsErrorFree &= OutputPin && InnerOutput && CompilerContext.MovePinLinksToIntermediate(*OutputPin, *InnerOutput).CanSafeConnect(); if (!bIsErrorFree) { CompilerContext.MessageLog.Error(*LOCTEXT("InternalConnectionError", "K2Node_ConvertAsset: Internal connection error. @@").ToString(), this); } BreakAllNodeLinks(); } }
void UK2Node::ReallocatePinsDuringReconstruction(TArray<UEdGraphPin*>& /*OldPins*/) { AllocateDefaultPins(); }