Skip to content

Commit 43998d0

Browse files
committed
fix crash on promote to variable & tiny refactor
1 parent 96acf96 commit 43998d0

11 files changed

Lines changed: 277 additions & 844 deletions

Source/FunctionHandler/Public/FunctionHandlerTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ struct FUNCTIONHANDLER_API FFunctionHandler
4343
UFunction* ResolveFunctionFromClass() const;
4444

4545
#pragma endregion Query
46-
};
46+
};

Source/FunctionHandlerUncooked/Private/K2Node_ExecuteFunctionHandler.cpp

Lines changed: 1 addition & 199 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,15 @@
88
#include "BlueprintNodeSpawner.h"
99
#include "EdGraphSchema_K2.h"
1010
#include "K2Node_CallFunction.h"
11-
#include "K2Node_Variable.h"
12-
#include "K2Node_VariableGet.h"
13-
#include "K2Node_MakeFunctionHandler.h"
1411
#include "KismetCompiler.h"
15-
#include "Kismet2/BlueprintEditorUtils.h"
1612

1713
#include "UObject/UnrealType.h"
1814

1915
#define LOCTEXT_NAMESPACE "K2Node_ExecuteFunctionHandler"
2016

2117
const FName UK2Node_ExecuteFunctionHandler::PN_Target(TEXT("Target"));
22-
const FName UK2Node_ExecuteFunctionHandler::PN_Handler(TEXT("Handler"));
2318
const FName UK2Node_ExecuteFunctionHandler::PN_Success(TEXT("Success"));
2419

25-
#pragma region UK2Node
26-
2720
void UK2Node_ExecuteFunctionHandler::AllocateDefaultPins()
2821
{
2922
CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Exec, UEdGraphSchema_K2::PN_Execute);
@@ -119,7 +112,6 @@ void UK2Node_ExecuteFunctionHandler::ExpandNode(
119112
GetterNode->SetFromFunction(GetResultFunc);
120113
GetterNode->AllocateDefaultPins();
121114

122-
// Chain exec: previous → GetterNode → next.
123115
LastExecOut->MakeLinkTo(GetterNode->FindPinChecked(UEdGraphSchema_K2::PN_Execute));
124116
LastExecOut = GetterNode->FindPinChecked(UEdGraphSchema_K2::PN_Then);
125117

@@ -138,7 +130,6 @@ void UK2Node_ExecuteFunctionHandler::ExpandNode(
138130
}
139131
}
140132

141-
// Wire final exec out to our Then pin.
142133
CompilerContext.MovePinLinksToIntermediate(
143134
*FindPinChecked(UEdGraphSchema_K2::PN_Then),
144135
*LastExecOut);
@@ -152,7 +143,6 @@ FText UK2Node_ExecuteFunctionHandler::GetNodeTitle(ENodeTitleType::Type TitleTyp
152143
{
153144
return LOCTEXT("NodeTitle", "Execute Function Handler");
154145
}
155-
156146
return FText::Format(
157147
LOCTEXT("NodeTitleWithFunc", "Execute Handler: {0}"),
158148
FText::FromName(CachedFunctionName));
@@ -163,11 +153,6 @@ FText UK2Node_ExecuteFunctionHandler::GetTooltipText() const
163153
return LOCTEXT("Tooltip", "Execute a function on the target using stored parameters from the handler, with typed result outputs.");
164154
}
165155

166-
FText UK2Node_ExecuteFunctionHandler::GetMenuCategory() const
167-
{
168-
return LOCTEXT("MenuCategory", "FunctionHandler");
169-
}
170-
171156
void UK2Node_ExecuteFunctionHandler::GetMenuActions(
172157
FBlueprintActionDatabaseRegistrar& ActionRegistrar) const
173158
{
@@ -186,55 +171,12 @@ void UK2Node_ExecuteFunctionHandler::ReallocatePinsDuringReconstruction(
186171
RestoreSplitPins(OldPins);
187172
}
188173

189-
void UK2Node_ExecuteFunctionHandler::PinConnectionListChanged(UEdGraphPin* Pin)
190-
{
191-
Super::PinConnectionListChanged(Pin);
192-
193-
if (Pin && Pin->PinName == PN_Handler)
194-
{
195-
RefreshFromHandler();
196-
}
197-
}
198-
199174
void UK2Node_ExecuteFunctionHandler::PinDefaultValueChanged(UEdGraphPin* Pin)
200175
{
201176
Super::PinDefaultValueChanged(Pin);
202177
RefreshFromHandler();
203178
}
204179

205-
void UK2Node_ExecuteFunctionHandler::PostReconstructNode()
206-
{
207-
Super::PostReconstructNode();
208-
BindBlueprintCompileDelegate();
209-
}
210-
211-
void UK2Node_ExecuteFunctionHandler::PostPasteNode()
212-
{
213-
Super::PostPasteNode();
214-
RefreshFromHandler();
215-
}
216-
217-
void UK2Node_ExecuteFunctionHandler::DestroyNode()
218-
{
219-
UnbindBlueprintCompileDelegate();
220-
Super::DestroyNode();
221-
}
222-
223-
FSlateIcon UK2Node_ExecuteFunctionHandler::GetIconAndTint(FLinearColor& OutColor) const
224-
{
225-
OutColor = FLinearColor(0.8f, 0.3f, 0.05f);
226-
return FSlateIcon(FAppStyle::GetAppStyleSetName(), "Kismet.AllClasses.FunctionIcon");
227-
}
228-
229-
FLinearColor UK2Node_ExecuteFunctionHandler::GetNodeTitleColor() const
230-
{
231-
return FLinearColor(0.8f, 0.3f, 0.05f);
232-
}
233-
234-
#pragma endregion UK2Node
235-
236-
#pragma region Helpers
237-
238180
void UK2Node_ExecuteFunctionHandler::CreateOutputPinsForFunction(UFunction* Function)
239181
{
240182
const UEdGraphSchema_K2* Schema = GetDefault<UEdGraphSchema_K2>();
@@ -266,144 +208,4 @@ void UK2Node_ExecuteFunctionHandler::CreateOutputPinsForFunction(UFunction* Func
266208
}
267209
}
268210

269-
UFunction* UK2Node_ExecuteFunctionHandler::TryResolveHandlerFunction()
270-
{
271-
// Try to read from linked Handler variable.
272-
const UEdGraphPin* HandlerPin = FindPin(PN_Handler);
273-
if (HandlerPin && HandlerPin->LinkedTo.Num() == 1)
274-
{
275-
const UEdGraphPin* SourcePin = HandlerPin->LinkedTo[0];
276-
if (SourcePin)
277-
{
278-
// Resolve from MakeFunctionHandler node.
279-
const UK2Node_MakeFunctionHandler* MakeNode = Cast<UK2Node_MakeFunctionHandler>(SourcePin->GetOwningNode());
280-
if (MakeNode)
281-
{
282-
if (UFunction* Func = MakeNode->GetTargetFunction())
283-
{
284-
CachedTargetClass = MakeNode->TargetClass;
285-
CachedFunctionName = Func->GetFName();
286-
}
287-
}
288-
289-
// Resolve from variable getter via CDO.
290-
const UK2Node_VariableGet* VarGetNode = Cast<UK2Node_VariableGet>(SourcePin->GetOwningNode());
291-
if (VarGetNode)
292-
{
293-
const UBlueprint* BP = FBlueprintEditorUtils::FindBlueprintForNode(this);
294-
UClass* GenClass = BP ? (BP->GeneratedClass ? BP->GeneratedClass : BP->SkeletonGeneratedClass) : nullptr;
295-
if (GenClass)
296-
{
297-
const FStructProperty* StructProp = CastField<FStructProperty>(
298-
GenClass->FindPropertyByName(VarGetNode->GetVarName()));
299-
300-
if (StructProp && StructProp->Struct == FFunctionHandler::StaticStruct())
301-
{
302-
const UObject* CDO = GenClass->GetDefaultObject(false);
303-
if (CDO)
304-
{
305-
const FFunctionHandler* Handler = StructProp->ContainerPtrToValuePtr<FFunctionHandler>(CDO);
306-
if (Handler && Handler->IsValid() && Handler->TargetClass)
307-
{
308-
CachedTargetClass = Handler->TargetClass;
309-
CachedFunctionName = Handler->FunctionName;
310-
}
311-
}
312-
}
313-
}
314-
}
315-
316-
// Fallback: resolve from intermediate CallFunction node wrapping InternalMakeFunctionHandler.
317-
// This handles the case where MakeFunctionHandler was already expanded before us.
318-
if (CachedFunctionName.IsNone())
319-
{
320-
const UK2Node_CallFunction* CallNode = Cast<UK2Node_CallFunction>(SourcePin->GetOwningNode());
321-
if (CallNode)
322-
{
323-
static const FName InternalMakeName = GET_FUNCTION_NAME_CHECKED(UFunctionHandlerLibrary, InternalMakeFunctionHandler);
324-
if (CallNode->GetFunctionName() == InternalMakeName)
325-
{
326-
const UEdGraphPin* ClassPin = CallNode->FindPin(TEXT("TargetClass"));
327-
const UEdGraphPin* FuncNamePin = CallNode->FindPin(TEXT("FunctionName"));
328-
if (ClassPin && FuncNamePin)
329-
{
330-
UClass* ResolvedClass = Cast<UClass>(ClassPin->DefaultObject);
331-
FName ResolvedFuncName = FName(*FuncNamePin->DefaultValue);
332-
if (ResolvedClass && !ResolvedFuncName.IsNone())
333-
{
334-
CachedTargetClass = ResolvedClass;
335-
CachedFunctionName = ResolvedFuncName;
336-
}
337-
}
338-
}
339-
}
340-
}
341-
}
342-
}
343-
344-
// Fallback to cached values (during reconstruction when pins aren't linked yet).
345-
if (CachedTargetClass && !CachedFunctionName.IsNone())
346-
{
347-
return CachedTargetClass->FindFunctionByName(CachedFunctionName);
348-
}
349-
350-
return nullptr;
351-
}
352-
353-
void UK2Node_ExecuteFunctionHandler::RefreshFromHandler()
354-
{
355-
if (bIsRefreshing)
356-
{
357-
return;
358-
}
359-
360-
bIsRefreshing = true;
361-
362-
const FName OldFunctionName = CachedFunctionName;
363-
const TSubclassOf<UObject> OldTargetClass = CachedTargetClass;
364-
365-
// Clear cache to force a fresh read.
366-
CachedTargetClass = nullptr;
367-
CachedFunctionName = NAME_None;
368-
369-
TryResolveHandlerFunction();
370-
371-
if (CachedFunctionName != OldFunctionName || CachedTargetClass != OldTargetClass)
372-
{
373-
ReconstructNode();
374-
}
375-
376-
bIsRefreshing = false;
377-
}
378-
379-
void UK2Node_ExecuteFunctionHandler::BindBlueprintCompileDelegate()
380-
{
381-
UBlueprint* BP = FBlueprintEditorUtils::FindBlueprintForNode(this);
382-
if (!BP || BoundBlueprint == BP)
383-
{
384-
return;
385-
}
386-
387-
UnbindBlueprintCompileDelegate();
388-
389-
BP->OnCompiled().AddUObject(this, &UK2Node_ExecuteFunctionHandler::OnBlueprintCompiled);
390-
BoundBlueprint = BP;
391-
}
392-
393-
void UK2Node_ExecuteFunctionHandler::UnbindBlueprintCompileDelegate()
394-
{
395-
if (UBlueprint* BP = BoundBlueprint.Get())
396-
{
397-
BP->OnCompiled().RemoveAll(this);
398-
BoundBlueprint = nullptr;
399-
}
400-
}
401-
402-
void UK2Node_ExecuteFunctionHandler::OnBlueprintCompiled(UBlueprint* Blueprint)
403-
{
404-
RefreshFromHandler();
405-
}
406-
407-
#pragma endregion Helpers
408-
409-
#undef LOCTEXT_NAMESPACE
211+
#undef LOCTEXT_NAMESPACE

0 commit comments

Comments
 (0)