diff --git a/.gitignore b/.gitignore index 9a607fc2..35fe075c 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ luprex/ext/eris-master/test/persist luprex/ext/eris-master/test/unpersist GPF-output/** + +__pycache__/ +.clangd-query.pid diff --git a/Source/Integration/LuaCallNode.cpp b/Source/Integration/LuaCallNode.cpp index ee417892..f60a6d5c 100644 --- a/Source/Integration/LuaCallNode.cpp +++ b/Source/Integration/LuaCallNode.cpp @@ -77,22 +77,9 @@ FString UK2Node_LuaInvoke::RemovePrefix(FName Name, char Prefix) return FString(pname + 2); } -static FEdGraphPinType GetPinType(const FProperty *Property) -{ - FEdGraphPinType PinType; - bool IsWeak; - FName PinCat, PinSubCat; - UObject *PinSubCatObj = nullptr; - UEdGraphSchema_K2::GetPropertyCategoryInfo(Property, PinCat, PinSubCat, PinSubCatObj, IsWeak); - PinType.PinCategory = PinCat; - PinType.PinSubCategory = PinSubCat; - PinType.PinSubCategoryObject = PinSubCatObj; - return PinType; -} - UK2Node_LuaInvoke::UK2Node_LuaInvoke(const FObjectInitializer& ObjectInitializer) - : Super(ObjectInitializer), NodeTooltip(MakeTooltip()) + : Super(ObjectInitializer) { } @@ -102,47 +89,42 @@ UK2Node_LuaProbe::UK2Node_LuaProbe(const FObjectInitializer& ObjectInitializer) } -FText UK2Node_LuaInvoke::MakeTooltip() const +FText UK2Node_LuaInvoke::GetTooltipText() const { - // TODO: replace this string manipulation with text manipulation. - FString ArgTypes = UlxLuaCallLibrary::AllKnownArgumentTypes(); - FString RetTypes = UlxLuaCallLibrary::AllKnownReturnValueTypes(); - return FText::FromString(FString::Printf(TEXT( + static FText Tooltip = FText::FromString(FString::Printf(TEXT( "Call a Lua function.\n" "\n" "The lua function prototype must be a hardwired string which must look like\n" - "one of the following:\n" + "one of the following:\n" "\n" - " classname.funcname(int arg1, int arg2)\n" - " classname.funcname(int arg1, int arg2) : int ret1, int ret2\n" - " classname.funcname(int arg1, int arg2) : int ret1, int ret2, ...\n" + " classname.funcname(int arg1, int arg2)\n" + " classname.funcname(int arg1, int arg2) : int ret1, int ret2\n" + " classname.funcname(int arg1, int arg2) : int ret1, int ret2, ...\n" "\n" - "You must specify types for the argument and return value pins. The:\n" - "types that you may specify are:\n" + "You must specify types for the argument and return value pins. The\n" + "types that you may specify are:\n" "\n" - "Arguments: %s\n" + "Arguments: %s\n" "Return Values: %s\n" "\n" "The prototype is parsed to determine what lua function to call.\n" - "The lua call node will automatically add pins for the arguments and\n" - "return values. If the function has no return values, you can omit those\n" - "from the proto. If you put an ellipsis at the end of the return values,\n" - "then any additional return values will be collected into a\n" - "dynamically typed array of values which you can iterate over later.\n" - "\n" + "The lua call node will automatically add pins for the arguments and\n" + "return values. If the function has no return values, you can omit those\n" + "from the proto. If you put an ellipsis at the end of the return values,\n" + "then any additional return values will be collected into a\n" + "dynamically typed array of values which you can iterate over later.\n" + "\n" "Optionally, you may use the * wildcard for the classname. In that\n" "case, the class of the 'place' tangible will be used.\n" - "\n"), *ArgTypes, *RetTypes)); + "\n"), *UlxLuaCallLibrary::AllKnownArgumentTypes(), *UlxLuaCallLibrary::AllKnownReturnValueTypes())); + return Tooltip; } void UK2Node_LuaInvoke::AllocateDefaultPins() { + Pins.Reset(); Super::AllocateDefaultPins(); - CreateCorrectPins(); -} -void UK2Node_LuaInvoke::CreateCorrectPins() -{ if (LuaFunctionPrototype.IsEmpty()) { LuaFunctionPrototype = TEXT("class.func(int arg1, int arg2) : int ret1, int ret2"); @@ -157,62 +139,20 @@ void UK2Node_LuaInvoke::CreateCorrectPins() ErrorMsg = FString::Printf(TEXT("Syntax error in lua function prototype: %s"), *ParsedProto.ErrorMessage); } - // Transfer all pins to the old pins map and clear the pin list. - TMap OldPins; - for (auto It = Pins.CreateIterator(); It; ++It) - { - UEdGraphPin* CheckPin = *It; - OldPins.Add(CheckPin->PinName, CheckPin); - } - Pins.Empty(); - - // KeepPin is a function that moves a pin from the old pins - // map back onto the pins list. - auto KeepPin = [&](FName Name, FEdGraphPinType Type = FEdGraphPinType()) -> bool - { - UEdGraphPin **OldPin = OldPins.Find(Name); - if ((OldPin != nullptr) && (((*OldPin)->PinType == Type) || (Type.PinCategory == FName()))) - { - Pins.Emplace(*OldPin); - OldPins.Remove(Name); - return true; - } - return false; - }; - - if (!KeepPin(UEdGraphSchema_K2::PN_Execute)) - { - CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute); - } - - if (!KeepPin(UEdGraphSchema_K2::PN_Then)) - { - CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then); - } + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute); + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Then); if (!IsInvoke()) { - if (!KeepPin(ErrorPinName)) - { - CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, ErrorPinName); - } + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Exec, ErrorPinName); } - if (!KeepPin(FunctionPinName)) - { - UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, FunctionPinName); - } - - if (!KeepPin(PlacePinName)) - { - UEdGraphPin *P = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, AActor::StaticClass(), PlacePinName); - } - - // Copy the property names into the pins. - UEdGraphPin *FunctionPin = FindPinChecked(FunctionPinName); + UEdGraphPin *FunctionPin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_String, FunctionPinName); FunctionPin->DefaultValue = LuaFunctionPrototype; - // Create Argument pins in the correct order, reusing old pins where possible. + CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Object, AActor::StaticClass(), PlacePinName); + + // Create argument pins. for (const FlxParsedProto::Pin & Pin : ParsedProto.Arguments) { FName PrefixedName = AddPrefix(Pin.Name, 'A'); @@ -223,14 +163,12 @@ void UK2Node_LuaInvoke::CreateCorrectPins() ErrorMsg = FString::Printf(TEXT("Unknown argument type: %s"), *Pin.Type); continue; } - FEdGraphPinType PinType = GetPinType(Accessor->FindPropertyByName(TEXT("Value"))); - if (!KeepPin(PrefixedName, PinType)) - { - CreatePin(EGPD_Input, PinType, PrefixedName); - } + FEdGraphPinType PinType; + GetDefault()->ConvertPropertyToPinType(Accessor->FindPropertyByName(TEXT("Value")), PinType); + CreatePin(EGPD_Input, PinType, PrefixedName); } - // Create ReturnValue pins in the correct order, reusing old pins where possible. + // Create return value pins. for (const FlxParsedProto::Pin & Pin : ParsedProto.ReturnValues) { FName PrefixedName = AddPrefix(Pin.Name, 'R'); @@ -241,28 +179,15 @@ void UK2Node_LuaInvoke::CreateCorrectPins() ErrorMsg = FString::Printf(TEXT("Unknown return value type: %s"), *Pin.Type); continue; } - FEdGraphPinType PinType = GetPinType(Accessor->FindPropertyByName(TEXT("Result"))); - if (!KeepPin(PrefixedName, PinType)) - { - CreatePin(EGPD_Output, PinType, PrefixedName); - } + FEdGraphPinType PinType; + GetDefault()->ConvertPropertyToPinType(Accessor->FindPropertyByName(TEXT("Result")), PinType); + CreatePin(EGPD_Output, PinType, PrefixedName); } if (ParsedProto.ExtraReturnValues) { - if (!KeepPin(ExtraResultsPinName)) - { - CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Object, UlxLuaValues::StaticClass(), ExtraResultsPinName); - } + CreatePin(EGPD_Output, UEdGraphSchema_K2::PC_Object, UlxLuaValues::StaticClass(), ExtraResultsPinName); } - - // Delete any unused pins. - for (auto &iter : OldPins) - { - iter.Value->Modify(); - iter.Value->MarkAsGarbage(); - } - OldPins.Empty(); } @@ -280,20 +205,13 @@ FText UK2Node_LuaInvoke::GetNodeTitle(ENodeTitleType::Type TitleType) const FText UK2Node_LuaInvoke::GetPinDisplayName(const UEdGraphPin* Pin) const { - // The exec pins don't need labels. - if ((Pin->PinName == UEdGraphSchema_K2::PN_Execute) || (Pin->PinName == UEdGraphSchema_K2::PN_Then)) + // These pins don't need labels. + if ((Pin->PinName == UEdGraphSchema_K2::PN_Execute) || + (Pin->PinName == UEdGraphSchema_K2::PN_Then) || + (Pin->PinName == FunctionPinName)) { return FText::GetEmpty(); } - - // Many pins can go unlabeled if they have default values. - if (Pin->PinName == FunctionPinName) - { - if (Pin->LinkedTo.Num() == 0) - { - return FText::GetEmpty(); - } - } // For argument pins, we must strip off the Argument Pin Prefix. if (IsPrefix(Pin, 'A')) @@ -314,34 +232,18 @@ FText UK2Node_LuaInvoke::GetPinDisplayName(const UEdGraphPin* Pin) const void UK2Node_LuaInvoke::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) { Super::PostEditChangeProperty(PropertyChangedEvent); - GetGraph()->NotifyNodeChanged(this); -} - -void UK2Node_LuaInvoke::PinConnectionListChanged(UEdGraphPin* Pin) -{ - Modify(); + // GetGraph()->NotifyNodeChanged(this); } void UK2Node_LuaInvoke::PinDefaultValueChanged(UEdGraphPin* Pin) { - if(Pin->PinName == FunctionPinName) + if ((Pin->PinName == FunctionPinName) && (Pin->DefaultValue != LuaFunctionPrototype)) { LuaFunctionPrototype = Pin->DefaultValue; - CreateCorrectPins(); - GetGraph()->NotifyNodeChanged(this); + ReconstructNode(); } } -FText UK2Node_LuaInvoke::GetTooltipText() const -{ - return NodeTooltip; -} - -void UK2Node_LuaInvoke::PostReconstructNode() -{ - Super::PostReconstructNode(); - CreateCorrectPins(); -} #define LuaCallLibraryFunction(name) (UlxLuaCallLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxLuaCallLibrary, name))) @@ -407,7 +309,7 @@ void UK2Node_LuaInvoke::ExpandNode(class FKismetCompilerContext& CompilerContext if (IsInvoke()) { // Make sure we didn't have return values for an invoke. - if (IsInvoke() && ((ParsedProto.ReturnValues.Num() > 0) || (ParsedProto.ExtraReturnValues))) + if ((ParsedProto.ReturnValues.Num() > 0) || (ParsedProto.ExtraReturnValues)) { CompilerContext.MessageLog.Error(TEXT("Lua Call in Invoke mode does not support return values")); } @@ -457,47 +359,13 @@ void UK2Node_LuaInvoke::ExpandNode(class FKismetCompilerContext& CompilerContext UK2Node::ERedirectType UK2Node_LuaInvoke::DoPinsMatchForReconstruction(const UEdGraphPin* NewPin, int32 NewPinIndex, const UEdGraphPin* OldPin, int32 OldPinIndex) const { - ERedirectType RedirectType = ERedirectType_None; - - // if the pin names do match - if (NewPin->PinName.ToString().Equals(OldPin->PinName.ToString(), ESearchCase::CaseSensitive)) + if ((NewPin->PinName == OldPin->PinName) && + (NewPin->Direction == OldPin->Direction) && + (NewPin->PinType == OldPin->PinType)) { - // Make sure we're not dealing with a menu node - UEdGraph* OuterGraph = GetGraph(); - if( OuterGraph && OuterGraph->Schema ) - { - const UEdGraphSchema_K2* K2Schema = Cast(GetSchema()); - if( !K2Schema || K2Schema->IsSelfPin(*NewPin) || K2Schema->ArePinTypesCompatible(OldPin->PinType, NewPin->PinType) ) - { - RedirectType = ERedirectType_Name; - } - else - { - RedirectType = ERedirectType_None; - } - } + return ERedirectType_Name; } - else - { - // try looking for a redirect if it's a K2 node - if (UK2Node* Node = Cast(NewPin->GetOwningNode())) - { - // if you don't have matching pin, now check if there is any redirect param set - TArray OldPinNames; - GetRedirectPinNames(*OldPin, OldPinNames); - - FName NewPinName; - RedirectType = ShouldRedirectParam(OldPinNames, /*out*/ NewPinName, Node); - - // make sure they match - if ((RedirectType != ERedirectType_None) && (!NewPin->PinName.ToString().Equals(NewPinName.ToString(), ESearchCase::CaseSensitive))) - { - RedirectType = ERedirectType_None; - } - } - } - - return RedirectType; + return ERedirectType_None; } bool UK2Node_LuaInvoke::IsConnectionDisallowed(const UEdGraphPin* MyPin, const UEdGraphPin* OtherPin, FString& OutReason) const diff --git a/Source/Integration/LuaCallNode.h b/Source/Integration/LuaCallNode.h index 626191b5..1fc8887a 100644 --- a/Source/Integration/LuaCallNode.h +++ b/Source/Integration/LuaCallNode.h @@ -36,7 +36,6 @@ class UK2Node_LuaInvoke : public UK2Node virtual void AllocateDefaultPins() override; virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override; virtual bool ShouldShowNodeProperties() const override { return true; } - virtual void PinConnectionListChanged(UEdGraphPin* Pin) override; virtual void PinDefaultValueChanged(UEdGraphPin* Pin) override; virtual FText GetTooltipText() const override; virtual FText GetPinDisplayName(const UEdGraphPin* Pin) const override; @@ -44,7 +43,6 @@ class UK2Node_LuaInvoke : public UK2Node //~ Begin UK2Node Interface. virtual bool IsNodePure() const override { return false; } - virtual void PostReconstructNode() override; virtual bool NodeCausesStructuralBlueprintChange() const override { return true; } virtual void ExpandNode(class FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph) override; virtual ERedirectType DoPinsMatchForReconstruction(const UEdGraphPin* NewPin, int32 NewPinIndex, const UEdGraphPin* OldPin, int32 OldPinIndex) const override; @@ -58,11 +56,6 @@ private: virtual bool IsInvoke() const { return true; } - FText MakeTooltip() const; - - /** Create all necessary pins. */ - void CreateCorrectPins(); - /** Pin Names for the three built-in Pins **/ static const FName FunctionPinName; static const FName PlacePinName; @@ -79,8 +72,6 @@ private: UPROPERTY() FString LuaFunctionPrototype; - /** Tooltip text for this node. */ - FText NodeTooltip; }; UCLASS(MinimalAPI)