const TCHAR* UClassProperty::ImportText_Internal( const TCHAR* Buffer, void* Data, int32 PortFlags, UObject* Parent, FOutputDevice* ErrorText ) const { const TCHAR* Result = UObjectProperty::ImportText_Internal( Buffer, Data, PortFlags, Parent, ErrorText ); if( Result ) { // Validate metaclass. UClass* C = (UClass*)GetObjectPropertyValue(Data); if (C && (!dynamic_cast<UClass*>(C) || !C->IsChildOf(MetaClass))) { // the object we imported doesn't implement our interface class ErrorText->Logf(TEXT("Invalid object '%s' specified for property '%s'"), *C->GetFullName(), *GetName()); SetObjectPropertyValue(Data, NULL); Result = NULL; } } return Result; }
bool FContentComparisonHelper::CompareClasses(const FString& InBaseClassName, const TArray<FString>& InBaseClassesToIgnore, int32 InRecursionDepth) { TMap<FString,TArray<FContentComparisonAssetInfo> > ClassToAssetsMap; UClass* TheClass = (UClass*)StaticFindObject(UClass::StaticClass(), ANY_PACKAGE, *InBaseClassName, true); if (TheClass != NULL) { TArray<UClass*> IgnoreBaseClasses; for (int32 IgnoreIdx = 0; IgnoreIdx < InBaseClassesToIgnore.Num(); IgnoreIdx++) { UClass* IgnoreClass = (UClass*)StaticFindObject(UClass::StaticClass(), ANY_PACKAGE, *(InBaseClassesToIgnore[IgnoreIdx]), true); if (IgnoreClass != NULL) { IgnoreBaseClasses.Add(IgnoreClass); } } for( TObjectIterator<UClass> It; It; ++It ) { UClass* TheAssetClass = *It; if ((TheAssetClass->IsChildOf(TheClass) == true) && (TheAssetClass->HasAnyClassFlags(CLASS_Abstract) == false)) { bool bSkipIt = false; for (int32 CheckIdx = 0; CheckIdx < IgnoreBaseClasses.Num(); CheckIdx++) { UClass* CheckClass = IgnoreBaseClasses[CheckIdx]; if (TheAssetClass->IsChildOf(CheckClass) == true) { // UE_LOG(LogEngineUtils, Warning, TEXT("Skipping class derived from other content comparison class...")); // UE_LOG(LogEngineUtils, Warning, TEXT("\t%s derived from %s"), *TheAssetClass->GetFullName(), *CheckClass->GetFullName()); bSkipIt = true; } } if (bSkipIt == false) { TArray<FContentComparisonAssetInfo>* AssetList = ClassToAssetsMap.Find(TheAssetClass->GetFullName()); if (AssetList == NULL) { TArray<FContentComparisonAssetInfo> TempAssetList; ClassToAssetsMap.Add(TheAssetClass->GetFullName(), TempAssetList); AssetList = ClassToAssetsMap.Find(TheAssetClass->GetFullName()); } check(AssetList); // Serialize object with reference collector. const int32 MaxRecursionDepth = 6; InRecursionDepth = FMath::Clamp<int32>(InRecursionDepth, 1, MaxRecursionDepth); TMap<UObject*,bool> RecursivelyGatheredReferences; RecursiveObjectCollection(TheAssetClass, 0, InRecursionDepth, RecursivelyGatheredReferences); // Add them to the asset list for (TMap<UObject*,bool>::TIterator GatheredIt(RecursivelyGatheredReferences); GatheredIt; ++GatheredIt) { UObject* Object = GatheredIt.Key(); if (Object) { bool bAddIt = true; if (ReferenceClassesOfInterest.Num() > 0) { FString CheckClassName = Object->GetClass()->GetName(); if (ReferenceClassesOfInterest.Find(CheckClassName) == NULL) { bAddIt = false; } } if (bAddIt == true) { int32 NewIndex = AssetList->AddZeroed(); FContentComparisonAssetInfo& Info = (*AssetList)[NewIndex]; Info.AssetName = Object->GetFullName(); Info.ResourceSize = Object->GetResourceSize(EResourceSizeMode::Inclusive); } } } } } } } else { UE_LOG(LogEngineUtils, Warning, TEXT("Failed to find class: %s"), *InBaseClassName); return false; } #if 0 // Log them all out UE_LOG(LogEngineUtils, Log, TEXT("CompareClasses on %s"), *InBaseClassName); for (TMap<FString,TArray<FContentComparisonAssetInfo>>::TIterator It(ClassToAssetsMap); It; ++It) { FString ClassName = It.Key(); TArray<FContentComparisonAssetInfo>& AssetList = It.Value(); UE_LOG(LogEngineUtils, Log, TEXT("\t%s"), *ClassName); for (int32 AssetIdx = 0; AssetIdx < AssetList.Num(); AssetIdx++) { FContentComparisonAssetInfo& Info = AssetList(AssetIdx); UE_LOG(LogEngineUtils, Log, TEXT("\t\t%s,%f"), *(Info.AssetName), Info.ResourceSize/1024.0f); } } #endif #if ALLOW_DEBUG_FILES // Write out a CSV file FString CurrentTime = FDateTime::Now().ToString(); FString Platform(FPlatformProperties::PlatformName()); FString BaseCSVName = ( FString(TEXT("ContentComparison/")) + FString::Printf(TEXT("ContentCompare-%s/"), *GEngineVersion.ToString()) + FString::Printf(TEXT("%s"), *InBaseClassName) ); // Handle file name length on consoles... FString EditedBaseClassName = InBaseClassName; FString TimeString = *FDateTime::Now().ToString(); FString CheckLenName = FString::Printf(TEXT("%s-%s.csv"),*InBaseClassName,*TimeString); if (CheckLenName.Len() > PLATFORM_MAX_FILEPATH_LENGTH) { while (CheckLenName.Len() > PLATFORM_MAX_FILEPATH_LENGTH) { EditedBaseClassName = EditedBaseClassName.Right(EditedBaseClassName.Len() - 1); CheckLenName = FString::Printf(TEXT("%s-%s.csv"),*EditedBaseClassName,*TimeString); } BaseCSVName = ( FString(TEXT("ContentComparison/")) + FString::Printf(TEXT("ContentCompare-%s/"), *GEngineVersion.ToString()) + FString::Printf(TEXT("%s"), *EditedBaseClassName) ); } FDiagnosticTableViewer* AssetTable = new FDiagnosticTableViewer( *FDiagnosticTableViewer::GetUniqueTemporaryFilePath(*BaseCSVName), true); if ((AssetTable != NULL) && (AssetTable->OutputStreamIsValid() == true)) { // Fill in the header row AssetTable->AddColumn(TEXT("Class")); AssetTable->AddColumn(TEXT("Asset")); AssetTable->AddColumn(TEXT("ResourceSize(kB)")); AssetTable->CycleRow(); // Fill it in for (TMap<FString,TArray<FContentComparisonAssetInfo> >::TIterator It(ClassToAssetsMap); It; ++It) { FString ClassName = It.Key(); TArray<FContentComparisonAssetInfo>& AssetList = It.Value(); AssetTable->AddColumn(*ClassName); AssetTable->CycleRow(); for (int32 AssetIdx = 0; AssetIdx < AssetList.Num(); AssetIdx++) { FContentComparisonAssetInfo& Info = AssetList[AssetIdx]; AssetTable->AddColumn(TEXT("")); AssetTable->AddColumn(*(Info.AssetName)); AssetTable->AddColumn(TEXT("%f"), Info.ResourceSize/1024.0f); AssetTable->CycleRow(); } } } else if (AssetTable != NULL) { // Created the class, but it failed to open the output stream. UE_LOG(LogEngineUtils, Warning, TEXT("Failed to open output stream in asset table!")); } if (AssetTable != NULL) { // Close it and kill it AssetTable->Close(); delete AssetTable; } #endif return true; }