// ©2023 Batty Bovine Productions, LLC. All Rights Reserved. #include "ComboActionSearchManager.h" #include "ComboActionGraph.h" #include "ComboInputAssets.h" #include "AssetRegistry/AssetRegistryModule.h" #include "Ed/EdComboActionGraph.h" #include "Nodes/ComboActionGraphNode.h" #include "Nodes/ComboActionGraphNode_ActionNodeBase.h" #include "Search/ComboActionSearchFilter.h" #define LOCTEXT_NAMESPACE "ComboActionSearchManager" FComboActionSearchManager *FComboActionSearchManager::Instance = nullptr; bool FComboActionSearchManager::QueryGraphNode(const FComboActionSearchFilter &SearchFilter, const UEdComboActionGraphNode *InGraphNode, const TSharedPtr &OutParentNode) const { if (SearchFilter.SearchString.IsEmpty() || !OutParentNode.IsValid() || !IsValid(InGraphNode)) { return false; } bool bContainsSearchString = false; const UComboActionGraphNode *Node = InGraphNode->ComboActionGraphNode; if (Node == nullptr) { return false; } const FString NodeType = Node->NodeTypeName.ToString(); const FText DisplayText = FText::Format(LOCTEXT("ComboActionNodeCategory", "Found results in {0}"), FText::FromString(NodeType)); const TSharedPtr TreeGraphNode = MakeShared(DisplayText, OutParentNode); TreeGraphNode->SetCategory(FText::FromString(NodeType)); TreeGraphNode->SetGraphNode(InGraphNode); if (bContainsSearchString) { OutParentNode->AddChild(TreeGraphNode); } // Search by Title if (SearchFilter.bIncludeNodeTitle) { if (Node->NodeTitle.ToString().Contains(SearchFilter.SearchString)) { bContainsSearchString = true; MakeChildTextNode ( TreeGraphNode, FText::FromName(FName(Node->NodeTitle.ToString() )), LOCTEXT("NodeTitleKey", "Node Title"), TEXT("Node Title") ); } } // Search by NodeTypeName if (SearchFilter.bIncludeNodeType) { if (Node->NodeTypeName.ToString().Contains(SearchFilter.SearchString)) { bContainsSearchString = true; this->MakeChildTextNode( TreeGraphNode, FText::FromName(FName(Node->NodeTypeName.ToString() )), LOCTEXT("NodeTypeKey", "Node Type"), TEXT("Node Type") ); } } // Search by Node Data if (SearchFilter.bIncludeNodeData) { if (const UComboActionGraphNode_ActionNodeBase *ActionNodeBase = Cast(Node)) { if (ActionNodeBase->GetComboInput()->GetName().Contains(SearchFilter.SearchString)) { bContainsSearchString = true; this->MakeChildTextNode( TreeGraphNode, FText::FromName(FName(Node->NodeTypeName.ToString())), LOCTEXT("NodeDataRowKey", "Node Data"), TEXT("Node Data") ); } } } // Search by GUID if (SearchFilter.bIncludeNodeGUID) { const FString FoundGUID = Node->GetNodeGUID().ToString(); if (FoundGUID.Contains(SearchFilter.SearchString)) { bContainsSearchString = true; MakeChildTextNode ( TreeGraphNode, FText::FromString(FoundGUID), LOCTEXT("NodeGUID", "Node GUID"), TEXT("Node GUID") ); } } if (bContainsSearchString) { OutParentNode->AddChild(TreeGraphNode); } return bContainsSearchString; } bool FComboActionSearchManager::QuerySingleAction(const FComboActionSearchFilter &SearchFilter, const UComboActionGraph *InAction, TSharedPtr &OutParentNode) { if (SearchFilter.SearchString.IsEmpty() || !OutParentNode.IsValid() || !IsValid(InAction)) { return false; } const UEdComboActionGraph *Graph = CastChecked(InAction->EdGraph); const TSharedPtr TreeActionNode = MakeShared(FText::FromString(InAction->GetPathName()), OutParentNode); TreeActionNode->SetActionGraph(Graph); // Find in GraphNodes bool bFoundInAction = false; const TArray &AllGraphNodes = Graph->Nodes; for (UEdGraphNode *Node : AllGraphNodes) { bool bFoundInNode = false; if (const UEdComboActionGraphNode *GraphNode = Cast(Node)) { bFoundInNode = this->QueryGraphNode(SearchFilter, GraphNode, TreeActionNode); } // Found at least one match in one of the nodes. bFoundInAction = bFoundInNode || bFoundInAction; } if (bFoundInAction) { OutParentNode->AddChild(TreeActionNode); } return bFoundInAction; } void FComboActionSearchManager::Initialize(TSharedPtr ParentTabCategory) { // Must ensure we do not attempt to load the AssetRegistry Module while saving a package, however, if it is loaded already we can safely obtain it this->AssetRegistry = &FModuleManager::LoadModuleChecked("AssetRegistry").Get(); this->OnAssetAddedHandle = this->AssetRegistry->OnAssetAdded().AddRaw(this, &FComboActionSearchManager::HandleOnAssetAdded); this->OnAssetRemovedHandle = this->AssetRegistry->OnAssetRemoved().AddRaw(this, &FComboActionSearchManager::HandleOnAssetRemoved); this->OnAssetRenamedHandle = this->AssetRegistry->OnAssetRenamed().AddRaw(this, &FComboActionSearchManager::HandleOnAssetRenamed); if (this->AssetRegistry->IsLoadingAssets()) { this->OnFilesLoadedHandle = this->AssetRegistry->OnFilesLoaded().AddRaw(this, &FComboActionSearchManager::HandleOnAssetRegistryFilesLoaded); } else { this->HandleOnAssetRegistryFilesLoaded(); } this->OnAssetLoadedHandle = FCoreUObjectDelegates::OnAssetLoaded.AddRaw(this, &FComboActionSearchManager::HandleOnAssetLoaded); } void FComboActionSearchManager::UnInitialize() { if (this->AssetRegistry) { if (this->OnAssetAddedHandle.IsValid()) { this->AssetRegistry->OnAssetAdded().Remove(this->OnAssetAddedHandle); this->OnAssetAddedHandle.Reset(); } if (this->OnAssetRemovedHandle.IsValid()) { this->AssetRegistry->OnAssetRemoved().Remove(this->OnAssetRemovedHandle); this->OnAssetRemovedHandle.Reset(); } if (this->OnFilesLoadedHandle.IsValid()) { this->AssetRegistry->OnFilesLoaded().Remove(this->OnFilesLoadedHandle); this->OnFilesLoadedHandle.Reset(); } if (this->OnAssetRenamedHandle.IsValid()) { this->AssetRegistry->OnAssetRenamed().Remove(this->OnAssetRenamedHandle); this->OnAssetRenamedHandle.Reset(); } } if (this->OnAssetLoadedHandle.IsValid()) { FCoreUObjectDelegates::OnAssetLoaded.Remove(this->OnAssetLoadedHandle); this->OnAssetLoadedHandle.Reset(); } } #undef LOCTEXT_NAMESPACE