Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6d7ac95
Search improvements vs. flow mainline
LindyHopperGT Jan 12, 2026
cc5b9c8
Flow Debugger Fixes
LindyHopperGT Jan 26, 2026
bd344f0
Merge remote-tracking branch 'upstream/5.x' into FlowDebuggerFixes
LindyHopperGT Jan 26, 2026
8e4fcf6
Reverted this fix for PR
LindyHopperGT Jan 26, 2026
f702cda
Merge remote-tracking branch 'upstream/5.x' into FlowDebuggerFixes
LindyHopperGT Jan 27, 2026
0008bf8
Merge remote-tracking branch 'upstream/5.x' into FlowDebuggerFixes
LindyHopperGT Jan 27, 2026
15fb280
restore changes from other PRs
MothDoctor Jan 27, 2026
ee0bcff
integrated usage of Flow Node as main parameter passed with breakpoin…
MothDoctor Jan 27, 2026
a5df994
Integrations with our version
LindyHopperGT Jan 27, 2026
e28dc7b
Merge branch 'FlowDebuggerFixes' of https://github.com/LindyHopperGT/…
LindyHopperGT Jan 27, 2026
ad4063a
compile fixes
LindyHopperGT Jan 27, 2026
7d4b31f
reverted formatting changes
MothDoctor Jan 28, 2026
1c00344
restored previous class layout
MothDoctor Jan 28, 2026
e94ca04
Merge branch '5.x' into FlowDebuggerFixes
MothDoctor Jan 28, 2026
12bb73c
Merge remote-tracking branch 'upstream/5.x' into FlowDebuggerFixes
LindyHopperGT Jan 28, 2026
a64dc47
Merge branch 'FlowDebuggerFixes' of https://github.com/LindyHopperGT/…
LindyHopperGT Jan 28, 2026
a6cee33
Merge remote-tracking branch 'upstream/5.x' into FlowDebuggerFixes
LindyHopperGT Jan 30, 2026
7fe6198
[Flow] Trigger Outputs deferred while processing an Input Trigger
LindyHopperGT Feb 5, 2026
64140b8
Merge remote-tracking branch 'upstream/5.x' into FlowDeferredTriggerQ…
LindyHopperGT Feb 5, 2026
83368bb
[Flow] DataPin support to AddOns
LindyHopperGT Feb 5, 2026
af26f13
[Flow] Data Pin Reroute support
LindyHopperGT Feb 6, 2026
c1cd11d
[Flow] Converted FlowDataPinValueSupplierInterface to C++ only
LindyHopperGT Feb 9, 2026
74717b5
Merge remote-tracking branch 'upstream/5.x' into FlowAssetParamsImpro…
LindyHopperGT Feb 11, 2026
1c03e3f
Flow Asset Params creation by Content Browser menu
LindyHopperGT Feb 11, 2026
e9a2c70
Flow Asset Params for subgraphs
LindyHopperGT Feb 11, 2026
01923c0
rather cosmetic changes
MothDoctor Feb 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Source/Flow/Private/Asset/FlowAssetParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,12 @@ void UFlowAssetParams::RebuildPropertiesMap()
}
#endif

bool UFlowAssetParams::CanSupplyDataPinValues_Implementation() const
bool UFlowAssetParams::CanSupplyDataPinValues() const
{
return !PropertyMap.IsEmpty();
}

FFlowDataPinResult UFlowAssetParams::TrySupplyDataPin_Implementation(FName PinName) const
FFlowDataPinResult UFlowAssetParams::TrySupplyDataPin(FName PinName) const
{
if (const TInstancedStruct<FFlowDataPinValue>* Found = PropertyMap.Find(PinName))
{
Expand Down
142 changes: 141 additions & 1 deletion Source/Flow/Private/Asset/FlowAssetParamsUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@
#include "Misc/DateTime.h"
#include "HAL/FileManager.h"

#if WITH_EDITOR
#include "Asset/FlowAssetParams.h"
#include "FlowLogChannels.h"

#include "AssetRegistry/AssetRegistryModule.h"
#include "AssetToolsModule.h"
#include "ContentBrowserModule.h"
#include "FileHelpers.h"
#include "IContentBrowserSingleton.h"
#include "Misc/MessageDialog.h"
#include "Modules/ModuleManager.h"
#include "SourceControlHelpers.h"
#endif

#include UE_INLINE_GENERATED_CPP_BY_NAME(FlowAssetParamsUtils)

#if WITH_EDITOR
Expand Down Expand Up @@ -116,4 +130,130 @@ bool FFlowAssetParamsUtils::ArePropertiesEqual(
return A.DataPinValue == B.DataPinValue;
}

#endif
UFlowAssetParams* FFlowAssetParamsUtils::CreateChildParamsAsset(UFlowAssetParams& ParentParams, const bool bShowDialogs, FText* OutOptionalFailureReason)
{
if (!IsValid(&ParentParams))
{
FailCreateChild(
NSLOCTEXT("FlowAssetParamsUtils", "InvalidParent", "Invalid Parent Flow Asset Params."),
bShowDialogs,
OutOptionalFailureReason);

return nullptr;
}

const FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");

const FString PackagePath = FPackageName::GetLongPackagePath(ParentParams.GetPackage()->GetPathName());
const FString BaseAssetName = ParentParams.GetName();

// Generate a unique name for the new asset params
FString UniquePackageName;
FString UniqueAssetName;
AssetToolsModule.Get().CreateUniqueAssetName(PackagePath + TEXT("/") + BaseAssetName, TEXT(""), UniquePackageName, UniqueAssetName);

if (UniqueAssetName.IsEmpty())
{
FailCreateChild(
FText::Format(
NSLOCTEXT("FlowAssetParamsUtils", "UniqueNameFail", "Failed to generate unique asset name for child params of {0}."),
FText::FromString(BaseAssetName)),
bShowDialogs,
OutOptionalFailureReason);

return nullptr;
}

// Create the new asset params
UFlowAssetParams* NewParams = Cast<UFlowAssetParams>(
AssetToolsModule.Get().CreateAsset(UniqueAssetName, PackagePath, ParentParams.GetClass(), nullptr));

if (!IsValid(NewParams))
{
FailCreateChild(
FText::Format(
NSLOCTEXT("FlowAssetParamsUtils", "CreateAssetFail", "Failed to create child Flow Asset Params: {0}."),
FText::FromString(UniqueAssetName)),
bShowDialogs,
OutOptionalFailureReason);

return nullptr;
}

// Best-effort source control integration (before save)
if (USourceControlHelpers::IsAvailable())
{
const FString FileName = USourceControlHelpers::PackageFilename(NewParams->GetPathName());
if (!USourceControlHelpers::CheckOutOrAddFile(FileName))
{
UE_LOG(LogFlow, Warning, TEXT("Failed to check out/add %s; saved in-memory only"), *NewParams->GetPathName());
}
}

// Configure from parent (copies OwnerFlowAsset + Properties, sets ParentParams, rebuilds PropertyMap, marks dirty)
NewParams->ConfigureFlowAssetParams(ParentParams.OwnerFlowAsset, &ParentParams, ParentParams.Properties);

// Reconcile (cycle detection, flattened inheritance, etc.)
const EFlowReconcilePropertiesResult ReconcileResult = NewParams->ReconcilePropertiesWithParentParams();
if (EFlowReconcilePropertiesResult_Classifiers::IsErrorResult(ReconcileResult))
{
FailCreateChild(
FText::Format(
NSLOCTEXT("FlowAssetParamsUtils", "ReconcileFail",
"Created asset but reconciliation failed.\n\nAsset: {0}\nError: {1}\n\nThe asset may be invalid and should be reviewed."),
FText::FromString(NewParams->GetPathName()),
UEnum::GetDisplayValueAsText(ReconcileResult)),
bShowDialogs,
OutOptionalFailureReason);

// Keep going: asset exists and may still be useful for debugging/fixing
}

// Save the package (force save even if not prompted)
{
UPackage* Package = NewParams->GetPackage();
TArray<UPackage*> PackagesToSave = { Package };

const bool bForceSave = true;
if (!UEditorLoadingAndSavingUtils::SavePackages(PackagesToSave, bForceSave))
{
FailCreateChild(
FText::Format(
NSLOCTEXT("FlowAssetParamsUtils", "SaveFail", "Failed to save child Flow Asset Params: {0}."),
FText::FromString(NewParams->GetPathName())),
bShowDialogs,
OutOptionalFailureReason);

// Still return the in-memory asset
}
}

// Register + sync to Content Browser
{
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
AssetRegistryModule.Get().AssetCreated(NewParams);

const FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked<FContentBrowserModule>("ContentBrowser");
const TArray<UObject*> AssetsToSync = { NewParams };
ContentBrowserModule.Get().SyncBrowserToAssets(AssetsToSync, true);
}

return NewParams;
}

void FFlowAssetParamsUtils::FailCreateChild(const FText& Reason, const bool bShowDialogs, FText* OutOptionalFailureReason)
{
if (OutOptionalFailureReason)
{
*OutOptionalFailureReason = Reason;
}

UE_LOG(LogFlow, Error, TEXT("%s"), *Reason.ToString());

if (bShowDialogs)
{
FMessageDialog::Open(EAppMsgType::Ok, Reason);
}
}

#endif
32 changes: 32 additions & 0 deletions Source/Flow/Private/Asset/FlowDeferredTransitionScope.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright https://github.com/MothCocoon/FlowGraph/graphs/contributors

#include "Asset/FlowDeferredTransitionScope.h"
#include "FlowAsset.h"
#include "Interfaces/FlowExecutionGate.h"

void FFlowDeferredTransitionScope::EnqueueDeferredTrigger(const FFlowDeferredTriggerInput& Entry)
{
check(bIsOpen);

DeferredTriggers.Add(Entry);
}

bool FFlowDeferredTransitionScope::TryFlushDeferredTriggers(UFlowAsset& OwningFlowAsset)
{
// Ensure the scope is closed before beginning flushing
CloseScope();

// Remove and trigger each deferred trigger input
while (!DeferredTriggers.IsEmpty() && !FFlowExecutionGate::IsHalted())
{
const FFlowDeferredTriggerInput Entry = DeferredTriggers[0];
DeferredTriggers.RemoveAt(0, 1, EAllowShrinking::No);

OwningFlowAsset.TriggerInput(Entry.NodeGuid, Entry.PinName, Entry.FromPin);
}

check(DeferredTriggers.IsEmpty() || FFlowExecutionGate::IsHalted());

// Return true if everything flushed without being interrupted by an ExecutionGate
return DeferredTriggers.IsEmpty();
}
Loading