FORCEINLINE FString BuildJsonStrFromMap(TMap<FString, FString> Map) { FString JsonStr; TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JsonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonStr); // Close the writer and finalize the output such that JsonStr has what we want TArray<FString> keys; Map.GetKeys(keys); JsonWriter->WriteObjectStart(); for (int32 k = 0; k < Map.Num(); k++) { JsonWriter->WriteValue(keys[k], Map[keys[k]]); } JsonWriter->WriteObjectEnd(); JsonWriter->Close(); return JsonStr; }
void FPhysxSharedData::DumpSharedMemoryUsage(FOutputDevice* Ar) { struct FSharedResourceEntry { uint64 MemorySize; uint64 Count; }; struct FSortBySize { FORCEINLINE bool operator()( const FSharedResourceEntry& A, const FSharedResourceEntry& B ) const { // Sort descending return B.MemorySize < A.MemorySize; } }; TMap<FString, FSharedResourceEntry> AllocationsByType; uint64 OverallSize = 0; int32 OverallCount = 0; TMap<FString, TArray<PxBase*> > ObjectsByType; for (int32 i=0; i < (int32)SharedObjects->getNbObjects(); ++i) { PxBase& Obj = SharedObjects->getObject(i); FString TypeName = ANSI_TO_TCHAR(Obj.getConcreteTypeName()); TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName); if (ObjectsArray == NULL) { ObjectsByType.Add(TypeName, TArray<PxBase*>()); ObjectsArray = ObjectsByType.Find(TypeName); } check(ObjectsArray); ObjectsArray->Add(&Obj); } TArray<FString> TypeNames; ObjectsByType.GetKeys(TypeNames); for (int32 TypeIdx=0; TypeIdx < TypeNames.Num(); ++TypeIdx) { const FString& TypeName = TypeNames[TypeIdx]; TArray<PxBase*>* ObjectsArray = ObjectsByType.Find(TypeName); check(ObjectsArray); PxSerializationRegistry* Sr = PxSerialization::createSerializationRegistry(*GPhysXSDK); PxCollection* Collection = PxCreateCollection(); for (int32 i=0; i < ObjectsArray->Num(); ++i) { Collection->add(*((*ObjectsArray)[i]));; } PxSerialization::complete(*Collection, *Sr); // chase all other stuff (shared shaps, materials, etc) needed to serialize this collection FPhysXCountMemoryStream Out; PxSerialization::serializeCollectionToBinary(Out, *Collection, *Sr); Collection->release(); Sr->release(); OverallSize += Out.UsedMemory; OverallCount += ObjectsArray->Num(); FSharedResourceEntry NewEntry; NewEntry.Count = ObjectsArray->Num(); NewEntry.MemorySize = Out.UsedMemory; AllocationsByType.Add(TypeName, NewEntry); } Ar->Logf(TEXT("")); Ar->Logf(TEXT("Shared Resources:")); Ar->Logf(TEXT("")); AllocationsByType.ValueSort(FSortBySize()); Ar->Logf(TEXT("%-10d %s (%d)"), OverallSize, TEXT("Overall"), OverallCount ); for( auto It=AllocationsByType.CreateConstIterator(); It; ++It ) { Ar->Logf(TEXT("%-10d %s (%d)"), It.Value().MemorySize, *It.Key(), It.Value().Count ); } }
void FPaperFlipbookHelpers::ExtractFlipbooksFromSprites(TMap<FString, TArray<UPaperSprite*> >& OutSpriteFlipbookMap, const TArray<UPaperSprite*>& Sprites, const TArray<FString>& InSpriteNames) { OutSpriteFlipbookMap.Reset(); // Local copy check((InSpriteNames.Num() == 0) || (InSpriteNames.Num() == Sprites.Num())); TArray<FString> SpriteNames = InSpriteNames; if (InSpriteNames.Num() == 0) { SpriteNames.Reset(); for (int32 SpriteIndex = 0; SpriteIndex < Sprites.Num(); ++SpriteIndex) { check(Sprites[SpriteIndex] != nullptr); SpriteNames.Add(Sprites[SpriteIndex]->GetName()); } } // Group them TMap<FString, UPaperSprite*> SpriteNameMap; TArray<UPaperSprite*> RemainingSprites; for (int32 SpriteIndex = 0; SpriteIndex < Sprites.Num(); ++SpriteIndex) { UPaperSprite* Sprite = Sprites[SpriteIndex]; const FString SpriteName = SpriteNames[SpriteIndex]; SpriteNameMap.Add(SpriteName, Sprite); int32 SpriteNumber = 0; FString SpriteBareString; if (ExtractSpriteNumber(SpriteName, /*out*/ SpriteBareString, /*out*/ SpriteNumber)) { SpriteBareString = ObjectTools::SanitizeObjectName(SpriteBareString); OutSpriteFlipbookMap.FindOrAdd(SpriteBareString).Add(Sprite); } else { RemainingSprites.Add(Sprite); } } // Natural sort using the same method as above struct FSpriteSortPredicate { FSpriteSortPredicate() {} // Sort predicate operator bool operator()(UPaperSprite& LHS, UPaperSprite& RHS) const { FString LeftString; int32 LeftNumber; ExtractSpriteNumber(LHS.GetName(), /*out*/ LeftString, /*out*/ LeftNumber); FString RightString; int32 RightNumber; ExtractSpriteNumber(RHS.GetName(), /*out*/ RightString, /*out*/ RightNumber); return (LeftString == RightString) ? (LeftNumber < RightNumber) : (LeftString < RightString); } }; // Sort sprites TArray<FString> Keys; OutSpriteFlipbookMap.GetKeys(Keys); for (auto SpriteName : Keys) { OutSpriteFlipbookMap[SpriteName].Sort(FSpriteSortPredicate()); } // Create a flipbook from all remaining sprites // Not sure if this is desirable behavior, might want one flipbook per sprite if (RemainingSprites.Num() > 0) { RemainingSprites.Sort(FSpriteSortPredicate()); const FString DesiredName = GetCleanerSpriteName(RemainingSprites[0]->GetName()) + TEXT("_Flipbook"); const FString SanitizedName = ObjectTools::SanitizeObjectName(DesiredName); OutSpriteFlipbookMap.Add(SanitizedName, RemainingSprites); } }