static FBPTerminal* CreateInnerTerm(FKismetFunctionContext& Context, UEdGraphPin* SelfPin, UEdGraphPin* NetPin, UMulticastDelegateProperty* BoundProperty, UK2Node_BaseMCDelegate * DelegateNode, FCompilerResultsLog& MessageLog) { check(SelfPin && NetPin && BoundProperty && DelegateNode); FBPTerminal* Term = new(Context.VariableReferences) FBPTerminal(); Term->CopyFromPin(SelfPin, BoundProperty->GetName()); Term->AssociatedVarProperty = BoundProperty; FBPTerminal** pContextTerm = Context.NetMap.Find(NetPin); if ((NULL == pContextTerm) && (SelfPin == NetPin)) { Context.NetMap.Add(SelfPin, Term); pContextTerm = Context.NetMap.Find(NetPin); } if (pContextTerm) { if (Term != *pContextTerm) { Term->Context = *pContextTerm; } } else { MessageLog.Error(*FString(*LOCTEXT("FindDynamicallyBoundDelegate_Error", "Couldn't find target for dynamically bound delegate node @@").ToString()), DelegateNode); } return Term; }
void FNodeHandlingFunctor::ResolveAndRegisterScopedTerm(FKismetFunctionContext& Context, UEdGraphPin* Net, TIndirectArray<FBPTerminal>& NetArray) { // Determine the scope this takes place in UStruct* SearchScope = Context.Function; UEdGraphPin* SelfPin = CompilerContext.GetSchema()->FindSelfPin(*(Net->GetOwningNode()), EGPD_Input); if (SelfPin != NULL) { SearchScope = Context.GetScopeFromPinType(SelfPin->PinType, Context.NewClass); } // Find the variable in the search scope UProperty* BoundProperty = FKismetCompilerUtilities::FindPropertyInScope(SearchScope, Net, CompilerContext.MessageLog, CompilerContext.GetSchema(), Context.NewClass); if (BoundProperty != NULL) { // Create the term in the list FBPTerminal* Term = new (NetArray) FBPTerminal(); Term->CopyFromPin(Net, Net->PinName); Term->AssociatedVarProperty = BoundProperty; Context.NetMap.Add(Net, Term); // Read-only variables and variables in const classes are both const if (BoundProperty->HasAnyPropertyFlags(CPF_BlueprintReadOnly) || Context.IsConstFunction()) { Term->bIsConst = true; } // Resolve the context term if (SelfPin != NULL) { FBPTerminal** pContextTerm = Context.NetMap.Find(FEdGraphUtilities::GetNetFromPin(SelfPin)); Term->Context = (pContextTerm != NULL) ? *pContextTerm : NULL; } } }
FBPTerminal* RegisterInputTerm(FKismetFunctionContext& Context, UK2Node_BreakStruct* Node) { check(NULL != Node); if(NULL == Node->StructType) { CompilerContext.MessageLog.Error(*LOCTEXT("BreakStruct_UnknownStructure_Error", "Unknown structure to break for @@").ToString(), Node); return NULL; } //Find input pin UEdGraphPin* InputPin = NULL; for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex) { UEdGraphPin* Pin = Node->Pins[PinIndex]; if(Pin && (EGPD_Input == Pin->Direction)) { InputPin = Pin; break; } } check(NULL != InputPin); //Find structure source net UEdGraphPin* Net = FEdGraphUtilities::GetNetFromPin(InputPin); check(NULL != Net); FBPTerminal** FoundTerm = Context.NetMap.Find(Net); FBPTerminal* Term = FoundTerm ? *FoundTerm : NULL; if(NULL == Term) { // Dont allow literal if ((Net->Direction == EGPD_Input) && (Net->LinkedTo.Num() == 0)) { CompilerContext.MessageLog.Error(*LOCTEXT("InvalidNoInputStructure_Error", "No input structure to break for @@").ToString(), Net); return NULL; } // standard register net else { Term = new (Context.IsEventGraph() ? Context.EventGraphLocals : Context.Locals) FBPTerminal(); Term->CopyFromPin(Net, Context.NetNameMap->MakeValidName(Net)); } Context.NetMap.Add(Net, Term); } UStruct* StructInTerm = Cast<UStruct>(Term->Type.PinSubCategoryObject.Get()); if(NULL == StructInTerm || !StructInTerm->IsChildOf(Node->StructType)) { CompilerContext.MessageLog.Error(*LOCTEXT("BreakStruct_NoMatch_Error", "Structures don't match for @@").ToString(), Node); } return Term; }
virtual void RegisterNet(FKismetFunctionContext& Context, UEdGraphPin* Net) override { // This net is an anonymous temporary variable FBPTerminal* Term = Context.CreateLocalTerminal(Context.IsEventGraph() ? ETerminalSpecification::TS_ForcedShared : ETerminalSpecification::TS_Unspecified); FString NetName = Context.NetNameMap->MakeValidName(Net); Term->CopyFromPin(Net, NetName); UK2Node_TemporaryVariable* TempVarNode = CastChecked<UK2Node_TemporaryVariable>(Net->GetOwningNode()); Term->bIsSavePersistent = TempVarNode->bIsPersistent; Context.NetMap.Add(Net, Term); }
void FKCHandler_MathExpression::RegisterNets(FKismetFunctionContext& Context, UEdGraphNode* InNode) { FNodeHandlingFunctor::RegisterNets(Context, InNode); auto Node_MathExpression = CastChecked<UK2Node_MathExpression>(InNode); auto InnerEntryNode = Node_MathExpression->GetEntryNode(); auto InnerExitNode = Node_MathExpression->GetExitNode(); check(Node_MathExpression->BoundGraph && InnerEntryNode && InnerExitNode); for (auto InnerGraphNode : Node_MathExpression->BoundGraph->Nodes) { if (!InnerGraphNode || (InnerGraphNode == InnerEntryNode) || (InnerGraphNode == InnerExitNode)) { continue; } if (auto GetVarNode = Cast<UK2Node_VariableGet>(InnerGraphNode)) { auto VarHandler = GetVarNode->CreateNodeHandler(CompilerContext); if (ensure(VarHandler)) { VarHandler->RegisterNets(Context, GetVarNode); } continue; } for (auto Pin : InnerGraphNode->Pins) { // Register fake terms for InlineGeneratedValues if (Pin && (Pin->Direction == EEdGraphPinDirection::EGPD_Output) && Pin->LinkedTo.Num()) { auto Linked = Pin->LinkedTo[0]; auto LinkedOwnerNode = Linked ? Linked->GetOwningNodeUnchecked() : nullptr; if (LinkedOwnerNode && (InnerExitNode != LinkedOwnerNode)) { FBPTerminal* Term = new (Context.InlineGeneratedValues) FBPTerminal(); Term->CopyFromPin(Pin, Context.NetNameMap->MakeValidName(Pin)); Context.NetMap.Add(Pin, Term); } } // Register Literals if (Pin && (Pin->Direction == EEdGraphPinDirection::EGPD_Input) && !Pin->LinkedTo.Num()) { RegisterLiteral(Context, Pin); } } } }
virtual void RegisterNet(FKismetFunctionContext& Context, UEdGraphPin* Net) override { // Do not register as a default any Pin that comes from being Split if (Net->ParentPin == nullptr) { for (auto& ResultTerm : Context.Results) { if ((ResultTerm.Name == Net->PinName) && (ResultTerm.Type == Net->PinType)) { Context.NetMap.Add(Net, &ResultTerm); return; } } FBPTerminal* Term = new (Context.Results) FBPTerminal(); Term->CopyFromPin(Net, Net->PinName); Context.NetMap.Add(Net, Term); } }
virtual void RegisterNets(FKismetFunctionContext& Context, UEdGraphNode* Node) override { UK2Node_GetArrayItem* ArrayNode = CastChecked<UK2Node_GetArrayItem>(Node); // return inline term if (Context.NetMap.Find(Node->Pins[2])) { Context.MessageLog.Error(*LOCTEXT("Error_ReturnTermAlreadyRegistered", "ICE: Return term is already registered @@").ToString(), Node); return; } { FBPTerminal* Term = new (Context.InlineGeneratedValues) FBPTerminal(); Term->CopyFromPin(Node->Pins[2], Context.NetNameMap->MakeValidName(Node->Pins[2])); Context.NetMap.Add(Node->Pins[2], Term); } FNodeHandlingFunctor::RegisterNets(Context, Node); }
void RegisterDelegateNet(FKismetFunctionContext& Context, UK2Node_DelegateSet* DelegateNode) { check(DelegateNode); UEdGraphPin* DelegatePin = DelegateNode->GetDelegateOwner(); check(DelegatePin); // Find the property on the specified scope UProperty* BoundProperty = NULL; for (TFieldIterator<UProperty> It(DelegateNode->DelegatePropertyClass, EFieldIteratorFlags::IncludeSuper); It; ++It) { UProperty* Prop = *It; if( Prop->GetFName() == DelegateNode->DelegatePropertyName ) { check(Prop->HasAllPropertyFlags(CPF_BlueprintAssignable)); BoundProperty = Prop; break; } } // Create a term for this property if( BoundProperty != NULL ) { FBPTerminal* Term = new(Context.VariableReferences) FBPTerminal(); Term->CopyFromPin(DelegatePin, DelegatePin->PinName); Term->AssociatedVarProperty = BoundProperty; Context.NetMap.Add(DelegatePin, Term); // Find the context for this term (the object owning the delegate property) FBPTerminal** pContextTerm = Context.NetMap.Find(FEdGraphUtilities::GetNetFromPin(DelegatePin)); if( pContextTerm ) { Term->Context = *pContextTerm; } else { CompilerContext.MessageLog.Error(*FString(*LOCTEXT("FindDynamicallyBoundDelegate_Error", "Couldn't find target for dynamically bound delegate node @@").ToString()), DelegateNode); } } }
void RegisterFunctionInput(FKismetFunctionContext& Context, UEdGraphPin* Net, UFunction* Function) { // This net is a parameter into the function FBPTerminal* Term = new (Context.Parameters) FBPTerminal(); Term->CopyFromPin(Net, Net->PinName); // Flag pass by reference parameters specially //@TODO: Still doesn't handle/allow users to declare new pass by reference, this only helps inherited functions if( Function ) { if (UProperty* ParentProperty = FindField<UProperty>(Function, FName(*(Net->PinName)))) { if (ParentProperty->HasAnyPropertyFlags(CPF_ReferenceParm)) { Term->bPassedByReference = true; } } } Context.NetMap.Add(Net, Term); }
void RegisterOutputTerm(FKismetFunctionContext& Context, UScriptStruct* StructType, UEdGraphPin* Net, FBPTerminal* ContextTerm) { UProperty* BoundProperty = FindField<UProperty>(StructType, *(Net->PinName)); if (BoundProperty != NULL) { FBPTerminal* Term = new (Context.IsEventGraph() ? Context.EventGraphLocals : Context.Locals) FBPTerminal(); Term->CopyFromPin(Net, Net->PinName); Term->AssociatedVarProperty = BoundProperty; Context.NetMap.Add(Net, Term); Term->Context = ContextTerm; if (BoundProperty->HasAnyPropertyFlags(CPF_BlueprintReadOnly)) { Term->bIsConst = true; } } else { CompilerContext.MessageLog.Error(TEXT("Failed to find a struct member for @@"), Net); } }