ComboInput/Source/ComboInputEditor/Private/Search/ComboActionSearchManager.cpp

260 lines
7.7 KiB
C++

// ©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<FComboActionSearchResult> &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<FComboActionSearchResult_GraphNode> TreeGraphNode = MakeShared<FComboActionSearchResult_GraphNode>(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<UComboActionGraphNode_ActionNodeBase>(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::QueryNodeDecorators(const FComboActionSearchFilter &SearchFilter, const FComboActionDecorator &InDecorator, const TSharedPtr<FComboActionSearchResult> &OutParentNode, int32 DecoratorIndex, FName DecoratorMemberName) const
{
if (SearchFilter.SearchString.IsEmpty() || !OutParentNode.IsValid())
{
return false;
}
bool bContainsSearchString = false;
if (InDecorator.DecoratorType == nullptr) return false;
// Search by Decorator Name
if (InDecorator.DecoratorType->GetName().Contains(SearchFilter.SearchString))
{
bContainsSearchString = true;
FString DecoratorName = InDecorator.DecoratorType->GetClass()->GetName();
// Format Name
{
if (DecoratorName.Contains(TEXT("_GEN_VARIABLE")))
{
DecoratorName.ReplaceInline(TEXT("_GEN_VARIABLE"), TEXT(""));
}
if(DecoratorName.EndsWith(TEXT("_C")) && DecoratorName.StartsWith(TEXT("Default__")))
{
DecoratorName.RightChopInline(9);
DecoratorName.LeftChopInline(2);
}
if (DecoratorName.EndsWith(TEXT("_C")))
{
DecoratorName.LeftChopInline(2);
}
}
const FText Category = FText::Format
(
LOCTEXT("DecoratorName", "Node Decorator: {0} at Index: {1}"),
FText::FromString(DecoratorName), FText::AsNumber(DecoratorIndex)
);
MakeChildTextNode
(
OutParentNode,
FText::FromString(DecoratorName),
Category,
Category.ToString()
);
}
return bContainsSearchString;
}
bool FComboActionSearchManager::QuerySingleAction(const FComboActionSearchFilter &SearchFilter, const UComboActionGraph *InAction, TSharedPtr<FComboActionSearchResult> &OutParentNode)
{
if (SearchFilter.SearchString.IsEmpty() || !OutParentNode.IsValid() || !IsValid(InAction))
{
return false;
}
const UEdComboActionGraph *Graph = CastChecked<UEdComboActionGraph>(InAction->EdGraph);
const TSharedPtr<FComboActionSearchResult_ActionNode> TreeActionNode = MakeShared<FComboActionSearchResult_ActionNode>(FText::FromString(InAction->GetPathName()), OutParentNode);
TreeActionNode->SetActionGraph(Graph);
// Find in GraphNodes
bool bFoundInAction = false;
const TArray<UEdGraphNode*> &AllGraphNodes = Graph->Nodes;
for (UEdGraphNode *Node : AllGraphNodes)
{
bool bFoundInNode = false;
if (const UEdComboActionGraphNode *GraphNode = Cast<UEdComboActionGraphNode>(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<FWorkspaceItem> 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<FAssetRegistryModule>("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