Delete MCPAssets and the things that use it.
This commit is contained in:
@@ -1,169 +0,0 @@
|
||||
#include "MCPAssets.h"
|
||||
#include "MCPServer.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "Engine/World.h"
|
||||
#include "Engine/Level.h"
|
||||
#include "Engine/LevelScriptBlueprint.h"
|
||||
#include "Materials/Material.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
#include "AssetRegistry/IAssetRegistry.h"
|
||||
|
||||
// ============================================================
|
||||
// MCPAssetsBase
|
||||
// ============================================================
|
||||
|
||||
MCPAssetsBase::MCPAssetsBase(UClass* InTargetClass)
|
||||
: TargetClass(InTargetClass)
|
||||
{
|
||||
Scans.Add(InTargetClass);
|
||||
}
|
||||
|
||||
MCPAssetsBase& MCPAssetsBase::Exact(const FString& InName)
|
||||
{
|
||||
MatchName = InName;
|
||||
bExactMatch = true;
|
||||
bPatternHasSlash = MatchName.Contains(TEXT("/"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPAssetsBase& MCPAssetsBase::Substring(const FString& InFilter)
|
||||
{
|
||||
MatchName = InFilter;
|
||||
bExactMatch = false;
|
||||
bPatternHasSlash = MatchName.Contains(TEXT("/"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPAssetsBase& MCPAssetsBase::NoDerived()
|
||||
{
|
||||
bNoDerived = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MCPAssetsBase& MCPAssetsBase::AllContent()
|
||||
{
|
||||
bAllContent = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool MCPAssetsBase::Info()
|
||||
{
|
||||
// In theory, there's no reason a person couldn't load/info
|
||||
// more than once, to obtain updates. Might as well allow it.
|
||||
AssetResults.Empty();
|
||||
UObjectResults.Empty();
|
||||
|
||||
// Query the asset registry
|
||||
IAssetRegistry& AR = FModuleManager::LoadModuleChecked<FAssetRegistryModule>("AssetRegistry").Get();
|
||||
|
||||
TArray<FAssetData> Candidates;
|
||||
AR.GetAssets(ConfigureFilter(), Candidates);
|
||||
for (const FAssetData &Data : Candidates)
|
||||
{
|
||||
if (AssetMatches(Data)) AssetResults.Add(Data);
|
||||
if (bErrorIfAny && (AssetResults.Num() > 0))
|
||||
{
|
||||
SetError(FString::Printf(TEXT("%s '%s' already exists."), *TargetClass->GetName(), *AssetResults[0].PackageName.ToString()));
|
||||
return false;
|
||||
}
|
||||
if (bErrorIfTwo && (AssetResults.Num() > 1))
|
||||
{
|
||||
SetError(FString::Printf(
|
||||
TEXT("Ambiguous %s name '%s' — matches '%s' and '%s'. Use the full package path to disambiguate."),
|
||||
*TargetClass->GetName(), *MatchName, *AssetResults[0].PackageName.ToString(), *AssetResults[1].PackageName.ToString()));
|
||||
return false;
|
||||
}
|
||||
if (AssetResults.Num() >= MaxResults) break;
|
||||
}
|
||||
|
||||
// Check error conditions on the result count
|
||||
if (bErrorIfNone && AssetResults.IsEmpty())
|
||||
{
|
||||
SetError(FString::Printf(TEXT("%s '%s' not found."), *TargetClass->GetName(), *MatchName));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MCPAssetsBase::Load()
|
||||
{
|
||||
if (!Info()) return false;
|
||||
|
||||
TArray<FAssetData> AssetsToLoad;
|
||||
Swap(AssetsToLoad, AssetResults);
|
||||
for (const FAssetData &Asset : AssetsToLoad)
|
||||
{
|
||||
UObject *Obj = TryLoadAsset(Asset);
|
||||
if (!Obj) continue;
|
||||
|
||||
// If this is a material open in the editor, use the editor's transient copy.
|
||||
if (UMaterial* Mat = Cast<UMaterial>(Obj))
|
||||
Obj = MCPUtils::ReplaceMaterialWithTransientCopy(Mat);
|
||||
|
||||
AssetResults.Add(Asset);
|
||||
UObjectResults.Add(Obj);
|
||||
}
|
||||
if (bErrorIfNone && AssetResults.IsEmpty())
|
||||
{
|
||||
SetError(FString::Printf(TEXT("%s '%s' exists but cannot be loaded."), *TargetClass->GetName(),
|
||||
*AssetsToLoad[0].PackageName.ToString()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
FARFilter MCPAssetsBase::ConfigureFilter()
|
||||
{
|
||||
FARFilter Filter;
|
||||
for (UClass* C : Scans) Filter.ClassPaths.Add(C->GetClassPathName());
|
||||
Filter.bRecursiveClasses = !bNoDerived;
|
||||
if (!bAllContent)
|
||||
{
|
||||
Filter.PackagePaths.Add(FName(TEXT("/Game")));
|
||||
Filter.bRecursivePaths = true;
|
||||
}
|
||||
return Filter;
|
||||
}
|
||||
|
||||
bool MCPAssetsBase::AssetMatches(const FAssetData &Asset)
|
||||
{
|
||||
if (bExactMatch)
|
||||
{
|
||||
FString Name = bPatternHasSlash ? Asset.PackageName.ToString() : Asset.AssetName.ToString();
|
||||
return Name.Equals(MatchName, ESearchCase::IgnoreCase);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Asset.AssetName.ToString().Contains(MatchName, ESearchCase::IgnoreCase) ||
|
||||
Asset.PackageName.ToString().Contains(MatchName, ESearchCase::IgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
UObject *MCPAssetsBase::TryLoadAsset(const FAssetData &Asset)
|
||||
{
|
||||
UObject* Obj = Asset.GetAsset();
|
||||
if (Obj == nullptr) return nullptr;
|
||||
if (Obj->IsA(TargetClass)) return Obj;
|
||||
|
||||
if (TargetClass->IsChildOf(UBlueprint::StaticClass()) &&
|
||||
ULevelScriptBlueprint::StaticClass()->IsChildOf(TargetClass))
|
||||
{
|
||||
UWorld* World = Cast<UWorld>(Obj);
|
||||
if (World && World->PersistentLevel)
|
||||
{
|
||||
ULevelScriptBlueprint* LevelBP = World->PersistentLevel->GetLevelScriptBlueprint(true);
|
||||
if (LevelBP) return LevelBP;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void MCPAssetsBase::SetError(const FString &Msg)
|
||||
{
|
||||
AssetResults.Empty();
|
||||
UObjectResults.Empty();
|
||||
UMCPServer::Printf(TEXT("ERROR: %s\n"), *Msg);
|
||||
}
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "MCPJson.h"
|
||||
#include "LogCapture.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "MCPAssets.h"
|
||||
#include "UObject/StrongObjectPtr.h"
|
||||
#include "Materials/MaterialExpression.h"
|
||||
#include "AssetRegistry/AssetRegistryModule.h"
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "AssetRegistry/AssetData.h"
|
||||
#include "MCPUtils.h"
|
||||
#include "Engine/Blueprint.h"
|
||||
#include "Engine/LevelScriptBlueprint.h"
|
||||
#include "Engine/World.h"
|
||||
|
||||
struct FARFilter;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// MCPAssets - search for assets.
|
||||
//
|
||||
//
|
||||
// Construct an object of class MCPAssets like this:
|
||||
//
|
||||
// MCPAssets<UBlueprint> Assets;
|
||||
//
|
||||
// The UBlueprint template parameter means that this example
|
||||
// Assets loader is capable of storing pointers to
|
||||
// UBlueprint.
|
||||
//
|
||||
// It also means that by default, it will scan
|
||||
// all UBlueprint assets. You can narrow that:
|
||||
//
|
||||
// Assets.NoScans();
|
||||
// Assets.Scan<UAnimBlueprint>();
|
||||
// Assets.Scan<ULuprexBlueprint>();
|
||||
//
|
||||
// To get string matching, call either 'Exact' or
|
||||
// 'Substring'. If you don't call either of these, there's
|
||||
// no string filter. If the string you pass in contains a
|
||||
// slash, then the search is by asset-path, otherwise, by
|
||||
// asset-name:
|
||||
//
|
||||
// Assets.Substring(TEXT("MyAsset"));
|
||||
//
|
||||
// By default, the asset finder limits itself to assets in
|
||||
// the /Game folder. You can expand that:
|
||||
//
|
||||
// Assets.AllContent();
|
||||
//
|
||||
// You can specify that you don't want to see derived
|
||||
// classes:
|
||||
//
|
||||
// Assets.NoDerived()
|
||||
//
|
||||
// You can specify a limit on the number of results
|
||||
// returned:
|
||||
//
|
||||
// Assets.Limit(100)
|
||||
//
|
||||
// You can specify what constitutes an error condition. If
|
||||
// the asset finder detects an error, then it will report
|
||||
// it:
|
||||
//
|
||||
// Assets.ENone() - it's an error if nothing is found
|
||||
// Assets.EAny() - it's an error if anything is found
|
||||
// Assets.ETwo() - it's an error if two or more are found
|
||||
//
|
||||
// Errors are reported via UMCPServer::Printf.
|
||||
//
|
||||
// Once the Assets object is configured, it's time to scan
|
||||
// the assets. Use 'Info' if you just want to see
|
||||
// FAssetData. Use 'Load' if you want to load the assets
|
||||
// into memory. Both of these functions return true if
|
||||
// there were no errors, or false if there was one.
|
||||
//
|
||||
// bool ok = Assets.Load();
|
||||
//
|
||||
// Once you've scanned the assets, you can examine the
|
||||
// results using the following methods. The objects array
|
||||
// will be empty if you called 'Info' instead of 'Load':
|
||||
//
|
||||
// const TArray<FAssetData>& AllData();
|
||||
// const FAssetData& OneData();
|
||||
// const TArray<UBlueprint*> Objects();
|
||||
// UBlueprint* Object();
|
||||
//
|
||||
//
|
||||
// MCPAssets configuration methods can be chained:
|
||||
//
|
||||
// Assets.Limit(100).ENone().ETwo();
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
class MCPAssetsBase
|
||||
{
|
||||
public:
|
||||
MCPAssetsBase& NoScans() { Scans.Empty(); return *this; }
|
||||
MCPAssetsBase& Scan(UClass* Class) { Scans.Add(Class); return *this; }
|
||||
template<class T> MCPAssetsBase& Scan() { return Scan(T::StaticClass()); }
|
||||
MCPAssetsBase& Exact(const FString& InName);
|
||||
MCPAssetsBase& Substring(const FString& InFilter);
|
||||
MCPAssetsBase& Limit(int32 Count) { MaxResults = Count; return *this; }
|
||||
MCPAssetsBase& NoDerived();
|
||||
MCPAssetsBase& AllContent();
|
||||
MCPAssetsBase& EAny() { bErrorIfAny = true; return *this; }
|
||||
MCPAssetsBase& ENone() { bErrorIfNone = true; return *this; }
|
||||
MCPAssetsBase& ETwo() { bErrorIfTwo = true; return *this; }
|
||||
|
||||
bool Load();
|
||||
bool Info();
|
||||
|
||||
const TArray<FAssetData>& AllData() const { return AssetResults; }
|
||||
const FAssetData& OneData() const { return AssetResults[0]; }
|
||||
|
||||
private:
|
||||
FARFilter ConfigureFilter();
|
||||
bool AssetMatches(const FAssetData &Data);
|
||||
UObject *TryLoadAsset(const FAssetData &Asset);
|
||||
void SetError(const FString &Msg);
|
||||
|
||||
protected:
|
||||
MCPAssetsBase(UClass* InTargetClass);
|
||||
|
||||
UClass* TargetClass;
|
||||
TSet<UClass*> Scans;
|
||||
TArray<FAssetData> AssetResults;
|
||||
TArray<UObject*> UObjectResults;
|
||||
FString MatchName;
|
||||
bool bExactMatch = false;
|
||||
bool bPatternHasSlash = false;
|
||||
bool bNoDerived = false;
|
||||
bool bAllContent = false;
|
||||
bool bErrorIfAny = false;
|
||||
bool bErrorIfNone = false;
|
||||
bool bErrorIfTwo = false;
|
||||
int32 MaxResults = 50;
|
||||
};
|
||||
|
||||
|
||||
template<class T>
|
||||
class MCPAssets : public MCPAssetsBase
|
||||
{
|
||||
public:
|
||||
MCPAssets() : MCPAssetsBase(T::StaticClass()) {}
|
||||
|
||||
TArrayView<T* const> Objects() const
|
||||
{
|
||||
return TArrayView<T* const>(reinterpret_cast<T* const*>(UObjectResults.GetData()), UObjectResults.Num());
|
||||
}
|
||||
T* Object() const { return UObjectResults.IsEmpty() ? nullptr : static_cast<T*>(UObjectResults[0]); }
|
||||
};
|
||||
Reference in New Issue
Block a user