156 lines
4.3 KiB
C++
156 lines
4.3 KiB
C++
|
|
// Portage UE 5.5 - voir LPCheckMeshAssignmentCommandlet.h
|
||
|
|
|
||
|
|
#include "LPCheckMeshAssignmentCommandlet.h"
|
||
|
|
|
||
|
|
#include "AssetRegistry/AssetRegistryModule.h"
|
||
|
|
#include "EdGraph/EdGraph.h"
|
||
|
|
#include "EdGraph/EdGraphPin.h"
|
||
|
|
#include "EdGraphSchema_K2.h"
|
||
|
|
#include "Engine/Blueprint.h"
|
||
|
|
#include "K2Node_CallFunction.h"
|
||
|
|
#include "UObject/UObjectGlobals.h"
|
||
|
|
|
||
|
|
DEFINE_LOG_CATEGORY_STATIC(LogLPCheckMesh, Log, All);
|
||
|
|
|
||
|
|
namespace
|
||
|
|
{
|
||
|
|
/** Noeuds qui nous interessent : tout ce qui lit ou ecrit le maillage d'un composant. */
|
||
|
|
bool IsMeshFunction(FName Name)
|
||
|
|
{
|
||
|
|
const FString S = Name.ToString();
|
||
|
|
return S.Contains(TEXT("SkinnedAsset")) || S.Contains(TEXT("SkeletalMesh"))
|
||
|
|
|| S.Contains(TEXT("PoseComponent")); // Set(Master|Leader)PoseComponent : renomme en 5.1
|
||
|
|
}
|
||
|
|
|
||
|
|
FString DescribePin(const UEdGraphPin* Pin)
|
||
|
|
{
|
||
|
|
if (!Pin)
|
||
|
|
{
|
||
|
|
return TEXT("(absente)");
|
||
|
|
}
|
||
|
|
|
||
|
|
const FString Type = Pin->PinType.PinSubCategoryObject.IsValid()
|
||
|
|
? Pin->PinType.PinSubCategoryObject->GetName()
|
||
|
|
: Pin->PinType.PinCategory.ToString();
|
||
|
|
|
||
|
|
if (Pin->LinkedTo.Num() == 0)
|
||
|
|
{
|
||
|
|
return FString::Printf(TEXT("[%s] NON CONNECTEE (defaut='%s')"),
|
||
|
|
*Type, *Pin->DefaultValue);
|
||
|
|
}
|
||
|
|
|
||
|
|
TArray<FString> Sources;
|
||
|
|
for (const UEdGraphPin* Linked : Pin->LinkedTo)
|
||
|
|
{
|
||
|
|
Sources.Add(FString::Printf(TEXT("%s.%s"),
|
||
|
|
Linked->GetOwningNode() ? *Linked->GetOwningNode()->GetName() : TEXT("?"),
|
||
|
|
*Linked->PinName.ToString()));
|
||
|
|
}
|
||
|
|
return FString::Printf(TEXT("[%s] <- %s"), *Type, *FString::Join(Sources, TEXT(", ")));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
ULPCheckMeshAssignmentCommandlet::ULPCheckMeshAssignmentCommandlet()
|
||
|
|
{
|
||
|
|
IsClient = false;
|
||
|
|
IsServer = false;
|
||
|
|
IsEditor = true;
|
||
|
|
LogToConsole = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
int32 ULPCheckMeshAssignmentCommandlet::Main(const FString& Params)
|
||
|
|
{
|
||
|
|
UE_LOG(LogLPCheckMesh, Warning, TEXT("=== Broches orphelines (supprimees par une migration) ==="));
|
||
|
|
|
||
|
|
FAssetRegistryModule& AssetRegistryModule =
|
||
|
|
FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT("AssetRegistry"));
|
||
|
|
AssetRegistryModule.Get().SearchAllAssets(true);
|
||
|
|
|
||
|
|
TArray<FAssetData> BlueprintAssets;
|
||
|
|
AssetRegistryModule.Get().GetAssetsByClass(UBlueprint::StaticClass()->GetClassPathName(), BlueprintAssets, true);
|
||
|
|
|
||
|
|
int32 Total = 0;
|
||
|
|
int32 Disconnected = 0;
|
||
|
|
|
||
|
|
for (const FAssetData& AssetData : BlueprintAssets)
|
||
|
|
{
|
||
|
|
if (!AssetData.PackageName.ToString().StartsWith(TEXT("/Game/")))
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
UBlueprint* Blueprint = Cast<UBlueprint>(AssetData.GetAsset());
|
||
|
|
if (!Blueprint)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
TArray<UEdGraph*> Graphs;
|
||
|
|
Blueprint->GetAllGraphs(Graphs);
|
||
|
|
|
||
|
|
for (UEdGraph* Graph : Graphs)
|
||
|
|
{
|
||
|
|
if (!Graph)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (UEdGraphNode* GraphNode : Graph->Nodes)
|
||
|
|
{
|
||
|
|
// Balayage general : toute broche que le moteur a marquee orpheline, quel que
|
||
|
|
// soit le noeud. C'est la trace exacte d'une broche supprimee par une montee
|
||
|
|
// de version alors qu'elle portait encore des liaisons ou une valeur.
|
||
|
|
// Nom de la fonction appelee, quand il y en a une : c'est lui qui dit
|
||
|
|
// quelle API a perdu sa broche.
|
||
|
|
FString Callee;
|
||
|
|
if (const UK2Node_CallFunction* Fn = Cast<UK2Node_CallFunction>(GraphNode))
|
||
|
|
{
|
||
|
|
Callee = FString::Printf(TEXT(" [%s]"), *Fn->FunctionReference.GetMemberName().ToString());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Un noeud ne nous interesse que s'il porte au moins une broche orpheline.
|
||
|
|
bool bHasOrphan = false;
|
||
|
|
for (const UEdGraphPin* Pin : GraphNode->Pins)
|
||
|
|
{
|
||
|
|
if (Pin && Pin->bOrphanedPin) { bHasOrphan = true; break; }
|
||
|
|
}
|
||
|
|
if (!bHasOrphan)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
UE_LOG(LogLPCheckMesh, Warning, TEXT(" %s :: %s -> %s%s"),
|
||
|
|
*Blueprint->GetName(), *Graph->GetName(), *GraphNode->GetName(), *Callee);
|
||
|
|
|
||
|
|
// On dumpe TOUTES les broches : l'orpheline porte l'ancienne valeur, et la
|
||
|
|
// broche de remplacement dit si la migration l'a reprise ou laissee vide.
|
||
|
|
for (UEdGraphPin* Pin : GraphNode->Pins)
|
||
|
|
{
|
||
|
|
if (!Pin || Pin->PinType.PinCategory == UEdGraphSchema_K2::PC_Exec)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
|
||
|
|
const bool bOrphan = Pin->bOrphanedPin;
|
||
|
|
if (bOrphan)
|
||
|
|
{
|
||
|
|
++Total;
|
||
|
|
if (Pin->LinkedTo.Num() > 0) { ++Disconnected; }
|
||
|
|
}
|
||
|
|
|
||
|
|
UE_LOG(LogLPCheckMesh, Warning, TEXT(" %-22s %-3s %s"),
|
||
|
|
*Pin->PinName.ToString(),
|
||
|
|
bOrphan ? TEXT("[X]") : TEXT(" "),
|
||
|
|
*DescribePin(Pin));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
UE_LOG(LogLPCheckMesh, Warning,
|
||
|
|
TEXT("=== Termine : %d broche(s) orpheline(s), dont %d portant encore des liaisons. ==="),
|
||
|
|
Total, Disconnected);
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|