diff --git a/Source/Flow/Private/FlowAsset.cpp b/Source/Flow/Private/FlowAsset.cpp index 0294a9a0..2ab2173d 100644 --- a/Source/Flow/Private/FlowAsset.cpp +++ b/Source/Flow/Private/FlowAsset.cpp @@ -1041,8 +1041,8 @@ void UFlowAsset::CancelAndWarnForUnflushedDeferredTriggers() if (TotalDroppedTriggers == 0 && !Triggers.IsEmpty()) { UE_LOG(LogFlow, Warning, TEXT("FlowAsset '%s' is finishing with %d lingering deferred transition scope(s) — dropping them. " - "This is usually unexpected and may indicate a bug or abnormal termination."), - *GetName(), DeferredTransitionScopes.Num()); + "This is usually unexpected and may indicate a bug or abnormal termination."), + *GetName(), DeferredTransitionScopes.Num()); } TotalDroppedTriggers += Triggers.Num(); @@ -1052,18 +1052,21 @@ void UFlowAsset::CancelAndWarnForUnflushedDeferredTriggers() const UFlowNode* ToNode = GetNode(Trigger.NodeGuid); const UFlowNode* FromNode = Trigger.FromPin.NodeGuid.IsValid() ? GetNode(Trigger.FromPin.NodeGuid) : nullptr; + const FString ToNodeName = ToNode ? ToNode->GetName() : TEXT(""); + const FString FromNodeName = FromNode ? FromNode->GetName() : TEXT(""); + UE_LOG(LogFlow, Error, - TEXT(" → Dropped deferred trigger:\n") - TEXT(" To Node: %s (%s)\n") - TEXT(" To Pin: %s\n") - TEXT(" From Node: %s (%s)\n") - TEXT(" From Pin: %s"), - *ToNode->GetName(), - *Trigger.NodeGuid.ToString(), - *Trigger.PinName.ToString(), - *FromNode->GetName(), - *Trigger.FromPin.NodeGuid.ToString(), - *Trigger.FromPin.PinName.ToString() + TEXT(" → Dropped deferred trigger:\n") + TEXT(" To Node: %s (%s)\n") + TEXT(" To Pin: %s\n") + TEXT(" From Node: %s (%s)\n") + TEXT(" From Pin: %s"), + *ToNodeName, + *Trigger.NodeGuid.ToString(), + *Trigger.PinName.ToString(), + *FromNodeName, + *Trigger.FromPin.NodeGuid.ToString(), + *Trigger.FromPin.PinName.ToString() ); } } @@ -1079,10 +1082,22 @@ bool UFlowAsset::HasStartedFlow() const AActor* UFlowAsset::TryFindActorOwner() const { - const UActorComponent* OwnerAsComponent = Cast(GetOwner()); - if (IsValid(OwnerAsComponent)) + UObject* OwnerObject = GetOwner(); + if (!IsValid(OwnerObject)) + { + return nullptr; + } + + // If the owner is already an Actor, return it directly + if (AActor* OwnerAsActor = Cast(OwnerObject)) { - return Cast(OwnerAsComponent->GetOwner()); + return OwnerAsActor; + } + + // If the owner is a Component, return its owning Actor + if (const UActorComponent* OwnerAsComponent = Cast(OwnerObject)) + { + return OwnerAsComponent->GetOwner(); } return nullptr; @@ -1418,37 +1433,22 @@ bool UFlowAsset::IsBoundToWorld_Implementation() const #if WITH_EDITOR void UFlowAsset::LogError(const FString& MessageToLog, const UFlowNodeBase* Node) const { - // this is runtime log which is should be only called on runtime instances of asset - if (TemplateAsset) - { - UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on asset instance %s"), *MessageToLog); - } - - if (RuntimeLog.Get()) - { - const TSharedRef TokenizedMessage = RuntimeLog.Get()->Error(*MessageToLog, Node); - BroadcastRuntimeMessageAdded(TokenizedMessage); - } + LogRuntimeMessage(EMessageSeverity::Error, MessageToLog, Node); } void UFlowAsset::LogWarning(const FString& MessageToLog, const UFlowNodeBase* Node) const { - // this is runtime log which is should be only called on runtime instances of asset - if (TemplateAsset) - { - UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on asset instance %s"), *MessageToLog); - } - - if (RuntimeLog.Get()) - { - const TSharedRef TokenizedMessage = RuntimeLog.Get()->Warning(*MessageToLog, Node); - BroadcastRuntimeMessageAdded(TokenizedMessage); - } + LogRuntimeMessage(EMessageSeverity::Warning, MessageToLog, Node); } void UFlowAsset::LogNote(const FString& MessageToLog, const UFlowNodeBase* Node) const { - // this is runtime log which is should be only called on runtime instances of asset + LogRuntimeMessage(EMessageSeverity::Info, MessageToLog, Node); +} + +void UFlowAsset::LogRuntimeMessage(EMessageSeverity::Type Severity, const FString& MessageToLog, const UFlowNodeBase* Node) const +{ + // this is runtime log which should only be called on runtime instances of asset if (TemplateAsset) { UE_LOG(LogFlow, Log, TEXT("Attempted to use Runtime Log on asset instance %s"), *MessageToLog); @@ -1456,8 +1456,23 @@ void UFlowAsset::LogNote(const FString& MessageToLog, const UFlowNodeBase* Node) if (RuntimeLog.Get()) { - const TSharedRef TokenizedMessage = RuntimeLog.Get()->Note(*MessageToLog, Node); - BroadcastRuntimeMessageAdded(TokenizedMessage); + TSharedPtr TokenizedMessage = nullptr; + switch (Severity) + { + case EMessageSeverity::Error: + TokenizedMessage = RuntimeLog.Get()->Error(*MessageToLog, Node); + break; + + case EMessageSeverity::Warning: + TokenizedMessage = RuntimeLog.Get()->Warning(*MessageToLog, Node); + break; + + default: + TokenizedMessage = RuntimeLog.Get()->Note(*MessageToLog, Node); + break; + } + + BroadcastRuntimeMessageAdded(TokenizedMessage.ToSharedRef()); } } -#endif +#endif \ No newline at end of file diff --git a/Source/Flow/Public/FlowAsset.h b/Source/Flow/Public/FlowAsset.h index dd0d5062..407676fc 100644 --- a/Source/Flow/Public/FlowAsset.h +++ b/Source/Flow/Public/FlowAsset.h @@ -484,5 +484,9 @@ class FLOW_API UFlowAsset : public UObject void LogError(const FString& MessageToLog, const UFlowNodeBase* Node) const; void LogWarning(const FString& MessageToLog, const UFlowNodeBase* Node) const; void LogNote(const FString& MessageToLog, const UFlowNodeBase* Node) const; + +private: + /* Shared implementation for LogError/LogWarning/LogNote to avoid code duplication. */ + void LogRuntimeMessage(EMessageSeverity::Type Severity, const FString& MessageToLog, const UFlowNodeBase* Node) const; #endif -}; +}; \ No newline at end of file