void UK2Node_CommutativeAssociativeBinaryOperator::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) { Super::ExpandNode(CompilerContext, SourceGraph); if (NumAdditionalInputs > 0) { const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema(); UEdGraphPin* LastOutPin = NULL; const UFunction* const Function = GetTargetFunction(); const UEdGraphPin* SrcOutPin = FindOutPin(); const UEdGraphPin* SrcSelfPin = FindSelfPin(); UEdGraphPin* SrcFirstInput = GetInputPin(0); check(SrcFirstInput); for(int32 PinIndex = 0; PinIndex < Pins.Num(); PinIndex++) { UEdGraphPin* CurrentPin = Pins[PinIndex]; if( (CurrentPin == SrcFirstInput) || (CurrentPin == SrcOutPin) || (SrcSelfPin == CurrentPin) ) { continue; } UK2Node_CommutativeAssociativeBinaryOperator* NewOperator = SourceGraph->CreateBlankNode<UK2Node_CommutativeAssociativeBinaryOperator>(); NewOperator->SetFromFunction(Function); NewOperator->AllocateDefaultPins(); CompilerContext.MessageLog.NotifyIntermediateObjectCreation(NewOperator, this); UEdGraphPin* NewOperatorInputA = NewOperator->GetInputPin(0); check(NewOperatorInputA); if(LastOutPin) { Schema->TryCreateConnection(LastOutPin, NewOperatorInputA); } else { // handle first created node (SrcFirstInput is skipped, and has no own node). CompilerContext.MovePinLinksToIntermediate(*SrcFirstInput, *NewOperatorInputA); } UEdGraphPin* NewOperatorInputB = NewOperator->GetInputPin(1); check(NewOperatorInputB); CompilerContext.MovePinLinksToIntermediate(*CurrentPin, *NewOperatorInputB); LastOutPin = NewOperator->FindOutPin(); check(LastOutPin); } UEdGraphPin* TrueOutPin = FindOutPin(); check(TrueOutPin); CompilerContext.MovePinLinksToIntermediate(*TrueOutPin, *LastOutPin); BreakAllNodeLinks(); } }
void UK2Node_MatineeController::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) { if (SourceGraph != CompilerContext.ConsolidatedEventGraph) { CompilerContext.MessageLog.Error(*FString::Printf(*NSLOCTEXT("KismetCompiler", "InvalidNodeOutsideUbergraph_Error", "Unexpected node @@ found outside ubergraph.").ToString()), this); return; } Super::ExpandNode(CompilerContext, SourceGraph); if (MatineeActor != NULL) { UFunction* MatineeEventSig = FindObject<UFunction>(AMatineeActor::StaticClass(), TEXT("OnMatineeEvent__DelegateSignature")); check(MatineeEventSig != NULL); const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema(); // Create event for each exec output pin for(int32 PinIdx=0; PinIdx<Pins.Num(); PinIdx++) { UEdGraphPin* MatineePin = Pins[PinIdx]; if(MatineePin->Direction == EGPD_Output && MatineePin->PinType.PinCategory == Schema->PC_Exec) { FName EventFuncName = MatineeActor->GetFunctionNameForEvent( FName(*(MatineePin->PinName)) ); UK2Node_Event* MatineeEventNode = CompilerContext.SpawnIntermediateNode<UK2Node_Event>(this, SourceGraph); MatineeEventNode->EventSignatureName = MatineeEventSig->GetFName(); MatineeEventNode->EventSignatureClass = AMatineeActor::StaticClass(); MatineeEventNode->CustomFunctionName = EventFuncName; MatineeEventNode->bInternalEvent = true; MatineeEventNode->AllocateDefaultPins(); // Move connection from matinee output to event node output UEdGraphPin* EventOutputPin = Schema->FindExecutionPin(*MatineeEventNode, EGPD_Output); check(EventOutputPin != NULL); CompilerContext.CheckConnectionResponse(Schema->MovePinLinks(*MatineePin, *EventOutputPin), this); } } } }
void UK2Node_InputKey::CreateInputKeyEvent(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph, UEdGraphPin* InputKeyPin, const EInputEvent KeyEvent) { if (InputKeyPin->LinkedTo.Num() > 0) { UK2Node_InputKeyEvent* InputKeyEvent = CompilerContext.SpawnIntermediateNode<UK2Node_InputKeyEvent>(this, SourceGraph); const FName ModifierName = GetModifierName(); if ( ModifierName != NAME_None ) { InputKeyEvent->CustomFunctionName = FName( *FString::Printf(TEXT("InpActEvt_%s_%s_%s"), *ModifierName.ToString(), *InputKey.ToString(), *InputKeyEvent->GetName())); } else { InputKeyEvent->CustomFunctionName = FName( *FString::Printf(TEXT("InpActEvt_%s_%s"), *InputKey.ToString(), *InputKeyEvent->GetName())); } InputKeyEvent->InputChord.Key = InputKey; InputKeyEvent->InputChord.bCtrl = bControl; InputKeyEvent->InputChord.bAlt = bAlt; InputKeyEvent->InputChord.bShift = bShift; InputKeyEvent->InputChord.bCmd = bCommand; InputKeyEvent->bConsumeInput = bConsumeInput; InputKeyEvent->bExecuteWhenPaused = bExecuteWhenPaused; InputKeyEvent->bOverrideParentBinding = bOverrideParentBinding; InputKeyEvent->InputKeyEvent = KeyEvent; InputKeyEvent->EventReference.SetExternalDelegateMember(FName(TEXT("InputActionHandlerDynamicSignature__DelegateSignature"))); InputKeyEvent->bInternalEvent = true; InputKeyEvent->AllocateDefaultPins(); // Move any exec links from the InputActionNode pin to the InputActionEvent node UEdGraphPin* EventOutput = CompilerContext.GetSchema()->FindExecutionPin(*InputKeyEvent, EGPD_Output); if(EventOutput != NULL) { CompilerContext.MovePinLinksToIntermediate(*InputKeyPin, *EventOutput); } } }
bool BuildLoop(UK2Node* Node, FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) { const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema(); check(Node && SourceGraph && Schema); bool bResult = true; // Create int Loop Counter UK2Node_TemporaryVariable* LoopCounterNode = CompilerContext.SpawnIntermediateNode<UK2Node_TemporaryVariable>(Node, SourceGraph); LoopCounterNode->VariableType.PinCategory = Schema->PC_Int; LoopCounterNode->AllocateDefaultPins(); LoopCounterOutPin = LoopCounterNode->GetVariablePin(); check(LoopCounterOutPin); // Initialize loop counter UK2Node_AssignmentStatement* LoopCounterInitialize = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(Node, SourceGraph); LoopCounterInitialize->AllocateDefaultPins(); LoopCounterInitialize->GetValuePin()->DefaultValue = TEXT("0"); bResult &= Schema->TryCreateConnection(LoopCounterOutPin, LoopCounterInitialize->GetVariablePin()); StartLoopExecInPin = LoopCounterInitialize->GetExecPin(); check(StartLoopExecInPin); // Create int Array Index UK2Node_TemporaryVariable* ArrayIndexNode = CompilerContext.SpawnIntermediateNode<UK2Node_TemporaryVariable>(Node, SourceGraph); ArrayIndexNode->VariableType.PinCategory = Schema->PC_Int; ArrayIndexNode->AllocateDefaultPins(); ArrayIndexOutPin = ArrayIndexNode->GetVariablePin(); check(ArrayIndexOutPin); // Initialize array index UK2Node_AssignmentStatement* ArrayIndexInitialize = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(Node, SourceGraph); ArrayIndexInitialize->AllocateDefaultPins(); ArrayIndexInitialize->GetValuePin()->DefaultValue = TEXT("0"); bResult &= Schema->TryCreateConnection(ArrayIndexOutPin, ArrayIndexInitialize->GetVariablePin()); bResult &= Schema->TryCreateConnection(LoopCounterInitialize->GetThenPin(), ArrayIndexInitialize->GetExecPin()); // Do loop branch UK2Node_IfThenElse* Branch = CompilerContext.SpawnIntermediateNode<UK2Node_IfThenElse>(Node, SourceGraph); Branch->AllocateDefaultPins(); bResult &= Schema->TryCreateConnection(ArrayIndexInitialize->GetThenPin(), Branch->GetExecPin()); LoopCompleteOutExecPin = Branch->GetElsePin(); check(LoopCompleteOutExecPin); // Do loop condition UK2Node_CallFunction* Condition = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(Node, SourceGraph); Condition->SetFromFunction(UKismetMathLibrary::StaticClass()->FindFunctionByName(TEXT("Less_IntInt"))); Condition->AllocateDefaultPins(); bResult &= Schema->TryCreateConnection(Condition->GetReturnValuePin(), Branch->GetConditionPin()); bResult &= Schema->TryCreateConnection(Condition->FindPinChecked(TEXT("A")), LoopCounterOutPin); LoopCounterLimitInPin = Condition->FindPinChecked(TEXT("B")); check(LoopCounterLimitInPin); // Array Index assigned UK2Node_AssignmentStatement* ArrayIndexAssign = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(Node, SourceGraph); ArrayIndexAssign->AllocateDefaultPins(); bResult &= Schema->TryCreateConnection(Branch->GetThenPin(), ArrayIndexAssign->GetExecPin()); bResult &= Schema->TryCreateConnection(ArrayIndexAssign->GetVariablePin(), ArrayIndexOutPin); bResult &= Schema->TryCreateConnection(ArrayIndexAssign->GetValuePin(), LoopCounterOutPin); // body sequence UK2Node_ExecutionSequence* Sequence = CompilerContext.SpawnIntermediateNode<UK2Node_ExecutionSequence>(Node, SourceGraph); Sequence->AllocateDefaultPins(); bResult &= Schema->TryCreateConnection(ArrayIndexAssign->GetThenPin(), Sequence->GetExecPin()); InsideLoopExecOutPin = Sequence->GetThenPinGivenIndex(0); check(InsideLoopExecOutPin); // Loop Counter increment UK2Node_CallFunction* Increment = CompilerContext.SpawnIntermediateNode<UK2Node_CallFunction>(Node, SourceGraph); Increment->SetFromFunction(UKismetMathLibrary::StaticClass()->FindFunctionByName(TEXT("Add_IntInt"))); Increment->AllocateDefaultPins(); bResult &= Schema->TryCreateConnection(Increment->FindPinChecked(TEXT("A")), LoopCounterOutPin); Increment->FindPinChecked(TEXT("B"))->DefaultValue = TEXT("1"); // Loop Counter assigned UK2Node_AssignmentStatement* LoopCounterAssign = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(Node, SourceGraph); LoopCounterAssign->AllocateDefaultPins(); bResult &= Schema->TryCreateConnection(LoopCounterAssign->GetExecPin(), Sequence->GetThenPinGivenIndex(1)); bResult &= Schema->TryCreateConnection(LoopCounterAssign->GetVariablePin(), LoopCounterOutPin); bResult &= Schema->TryCreateConnection(LoopCounterAssign->GetValuePin(), Increment->GetReturnValuePin()); bResult &= Schema->TryCreateConnection(LoopCounterAssign->GetThenPin(), Branch->GetExecPin()); return bResult; }
void UK2Node_InputAction::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) { Super::ExpandNode(CompilerContext, SourceGraph); UEdGraphPin* InputActionPressedPin = GetPressedPin(); UEdGraphPin* InputActionReleasedPin = GetReleasedPin(); struct EventPinData { EventPinData(UEdGraphPin* InPin,TEnumAsByte<EInputEvent> InEvent ){ Pin=InPin;EventType=InEvent;}; UEdGraphPin* Pin; TEnumAsByte<EInputEvent> EventType; }; TArray<EventPinData> ActivePins; if(( InputActionPressedPin != nullptr ) && (InputActionPressedPin->LinkedTo.Num() > 0 )) { ActivePins.Add(EventPinData(InputActionPressedPin,IE_Pressed)); } if((InputActionReleasedPin != nullptr) && (InputActionReleasedPin->LinkedTo.Num() > 0 )) { ActivePins.Add(EventPinData(InputActionReleasedPin,IE_Released)); } const UEdGraphSchema_K2* Schema = CompilerContext.GetSchema(); // If more than one is linked we have to do more complicated behaviors if( ActivePins.Num() > 1 ) { // Create a temporary variable to copy Key in to static UScriptStruct* KeyStruct = FKey::StaticStruct(); UK2Node_TemporaryVariable* ActionKeyVar = CompilerContext.SpawnIntermediateNode<UK2Node_TemporaryVariable>(this, SourceGraph); ActionKeyVar->VariableType.PinCategory = Schema->PC_Struct; ActionKeyVar->VariableType.PinSubCategoryObject = KeyStruct; ActionKeyVar->AllocateDefaultPins(); for (auto PinIt = ActivePins.CreateIterator(); PinIt; ++PinIt) { UEdGraphPin *EachPin = (*PinIt).Pin; // Create the input touch event UK2Node_InputActionEvent* InputActionEvent = CompilerContext.SpawnIntermediateNode<UK2Node_InputActionEvent>(this, SourceGraph); InputActionEvent->CustomFunctionName = FName( *FString::Printf(TEXT("InpActEvt_%s_%s"), *InputActionName.ToString(), *InputActionEvent->GetName())); InputActionEvent->InputActionName = InputActionName; InputActionEvent->bConsumeInput = bConsumeInput; InputActionEvent->bExecuteWhenPaused = bExecuteWhenPaused; InputActionEvent->bOverrideParentBinding = bOverrideParentBinding; InputActionEvent->InputKeyEvent = (*PinIt).EventType; InputActionEvent->EventReference.SetExternalDelegateMember(FName(TEXT("InputActionHandlerDynamicSignature__DelegateSignature"))); InputActionEvent->bInternalEvent = true; InputActionEvent->AllocateDefaultPins(); // Create assignment nodes to assign the key UK2Node_AssignmentStatement* ActionKeyInitialize = CompilerContext.SpawnIntermediateNode<UK2Node_AssignmentStatement>(this, SourceGraph); ActionKeyInitialize->AllocateDefaultPins(); Schema->TryCreateConnection(ActionKeyVar->GetVariablePin(), ActionKeyInitialize->GetVariablePin()); Schema->TryCreateConnection(ActionKeyInitialize->GetValuePin(), InputActionEvent->FindPinChecked(TEXT("Key"))); // Connect the events to the assign key nodes Schema->TryCreateConnection(Schema->FindExecutionPin(*InputActionEvent, EGPD_Output), ActionKeyInitialize->GetExecPin()); // Move the original event connections to the then pin of the key assign CompilerContext.MovePinLinksToIntermediate(*EachPin, *ActionKeyInitialize->GetThenPin()); // Move the original event variable connections to the intermediate nodes CompilerContext.MovePinLinksToIntermediate(*FindPin(TEXT("Key")), *ActionKeyVar->GetVariablePin()); } } else if( ActivePins.Num() == 1 ) { UEdGraphPin* InputActionPin = ActivePins[0].Pin; EInputEvent InputEvent = ActivePins[0].EventType; if (InputActionPin->LinkedTo.Num() > 0) { UK2Node_InputActionEvent* InputActionEvent = CompilerContext.SpawnIntermediateNode<UK2Node_InputActionEvent>(this, SourceGraph); InputActionEvent->CustomFunctionName = FName( *FString::Printf(TEXT("InpActEvt_%s_%s"), *InputActionName.ToString(), *InputActionEvent->GetName())); InputActionEvent->InputActionName = InputActionName; InputActionEvent->bConsumeInput = bConsumeInput; InputActionEvent->bExecuteWhenPaused = bExecuteWhenPaused; InputActionEvent->bOverrideParentBinding = bOverrideParentBinding; InputActionEvent->InputKeyEvent = InputEvent; InputActionEvent->EventReference.SetExternalDelegateMember(FName(TEXT("InputActionHandlerDynamicSignature__DelegateSignature"))); InputActionEvent->bInternalEvent = true; InputActionEvent->AllocateDefaultPins(); CompilerContext.MovePinLinksToIntermediate(*InputActionPin, *Schema->FindExecutionPin(*InputActionEvent, EGPD_Output)); CompilerContext.MovePinLinksToIntermediate(*FindPin(TEXT("Key")), *InputActionEvent->FindPin(TEXT("Key"))); } } }