154 lines
4.4 KiB
C++
154 lines
4.4 KiB
C++
#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 can be stored in variables, or in string builders,
|
|
// or in json trees. This example tells it to put error
|
|
// messages into a string variable:
|
|
//
|
|
// FString ErrorMessage;
|
|
// Assets.Errors(ErrorMessage)
|
|
//
|
|
// 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).Errors(ErrMsg).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& Errors(MCPErrorCallback InCB);
|
|
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;
|
|
MCPErrorCallback ErrorCB = MCPErrorCallback(nullptr);
|
|
};
|
|
|
|
|
|
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]); }
|
|
};
|