void UExporter::ExportComponentDefinitions(const FExportObjectInnerContext* Context, const TArray<UObject*>& Components, FOutputDevice& Ar, uint32 PortFlags) { PortFlags |= PPF_ExportsNotFullyQualified; if (!(PortFlags & PPF_SeparateDefine)) { // export forward declarations // technically we only need to do this if there are circular references but it doesn't seem worth it // to complicate this code for a minor speed improvement in the text import path for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++) { UObject* Component = Components[ComponentIndex]; FName ComponentName = Component->GetFName(); if (!Component->HasAnyMarks(OBJECTMARK_TagImp) && !Component->HasAnyFlags(RF_TextExportTransient)) { if (Component->HasAnyFlags(RF_ClassDefaultObject) || Component->GetArchetype()->HasAllFlags(RF_ClassDefaultObject)) { Ar.Logf(TEXT("%sBegin Object Class=%s Name=%s ObjName=%s%s"), FCString::Spc(TextIndent), *Component->GetClass()->GetName(), *ComponentName.ToString(), *Component->GetName(), LINE_TERMINATOR); } else { Ar.Logf(TEXT("%sBegin Object Class=%s Name=%s ObjName=%s Archetype=%s'%s'%s"),FCString::Spc(TextIndent),*Component->GetClass()->GetName(), *ComponentName.ToString(), *Component->GetName(), *Component->GetArchetype()->GetClass()->GetName(), *Component->GetArchetype()->GetPathName(), LINE_TERMINATOR); } if (PortFlags & PPF_SeparateDeclare) { ExportObjectInner(Context, Component, Ar, PortFlags, false); } Ar.Logf(TEXT("%sEnd Object%s"), FCString::Spc(TextIndent), LINE_TERMINATOR); } } } if (!(PortFlags & PPF_SeparateDeclare)) { // export property definitions for (int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++) { UObject* Component = Components[ComponentIndex]; FName ComponentName = Component->GetFName(); if (!Component->HasAnyMarks(OBJECTMARK_TagImp) && !Component->HasAnyFlags(RF_TextExportTransient)) { Ar.Logf(TEXT("%sBegin Object Name=%s%s"), FCString::Spc(TextIndent), *ComponentName.ToString(), LINE_TERMINATOR); uint32 OldPortFlags = PortFlags; if (!(Component->HasAnyFlags(RF_ClassDefaultObject) || Component->GetArchetype()->HasAllFlags(RF_ClassDefaultObject))) { // we created this thing with an archetype (see archetype=, above), so we don't want to list the archetype because it is unqualified and will clash, resetting the archetype pointer to something silly PortFlags |= PPF_NoInternalArcheType; } ExportObjectInner(Context, Component, Ar, PortFlags, false); PortFlags = OldPortFlags; Ar.Logf(TEXT("%sEnd Object%s"), FCString::Spc(TextIndent), LINE_TERMINATOR); Component->Mark(OBJECTMARK_TagImp); } } } }
void ConsoleCommandLibrary_DumpLibrary(UWorld* InWorld, FExec& SubSystem, const FString& Pattern, FOutputDevice& Ar) { ConsoleCommandLibrary LocalConsoleCommandLibrary(Pattern); FOutputDeviceNull Null; bool bExecuted = SubSystem.Exec( InWorld, *Pattern, Null); { IConsoleManager::Get().ForEachConsoleObjectThatStartsWith( FConsoleObjectVisitor::CreateStatic< TSet<FString>& >( &FConsoleVariableDumpVisitor::OnConsoleVariable, LocalConsoleCommandLibrary.KnownNames ) ); } LocalConsoleCommandLibrary.KnownNames.Sort( TLess<FString>() ); for(TSet<FString>::TConstIterator It(LocalConsoleCommandLibrary.KnownNames); It; ++It) { const FString Name = *It; Ar.Logf(TEXT("%s"), *Name); } Ar.Logf(TEXT("")); // the pattern (e.g. Motion*) should not really trigger the execution if(bExecuted) { Ar.Logf(TEXT("ERROR: The function was supposed to only find matching commands but not have any side effect.")); Ar.Logf(TEXT("However Exec() returned true which means we either executed a command or the command parsing returned true where it shouldn't.")); } }
void FObjectMemoryAnalyzer::PrintResults(FOutputDevice& Ar, uint32 PrintFlags) { TArray<FObjectMemoryUsage> Results; GetResults(Results); Results.Sort(FCompareFSortBySize(ESortKey::InclusiveTotal)); Ar.Logf( TEXT("%-100s %-10s %-10s %-10s %-10s"), TEXT("Object"), TEXT("InclBytes"), TEXT("ExclBytes"), TEXT("InclResKBytes"), TEXT("ExclResKBytes") ); for( int32 i=0; i < Results.Num(); ++i ) { const FObjectMemoryUsage& Annotation = Results[i]; if (Annotation.IsRoot() || (Annotation.RootReferencer.Num() == 0 && Annotation.NonRootReferencer.Num() == 0) ) { Ar.Logf( TEXT("%-100s %-10d %-10d %-10d %-10d"), *FString::Printf(TEXT("%s %s"), *Annotation.Object->GetClass()->GetName(), *Annotation.Object->GetName()), (int32)Annotation.InclusiveMemoryUsage, (int32)Annotation.ExclusiveMemoryUsage, (int32)(Annotation.InclusiveResourceSize/1024), (int32)(Annotation.ExclusiveResourceSize/1024) ); if (!!(PrintFlags&EPrintFlags::PrintReferences)) { PrintSubObjects(Ar, TEXT(" -> "), Annotation.Object, PrintFlags); } } } }
/** * Dump allocation information. */ void FBestFitAllocator::DumpAllocs( FOutputDevice& Ar/*=*GLog*/ ) { // Memory usage stats. INT UsedSize = 0; INT FreeSize = 0; INT NumUsedChunks = 0; INT NumFreeChunks = 0; // Fragmentation and allocation size visualization. INT NumBlocks = MemorySize / AllocationAlignment; INT Dimension = 1 + NumBlocks / appTrunc(appSqrt(NumBlocks)); TArray<FColor> AllocationVisualization; AllocationVisualization.AddZeroed( Dimension * Dimension ); INT VisIndex = 0; // Traverse linked list and gather allocation information. FMemoryChunk* CurrentChunk = FirstChunk; while( CurrentChunk ) { FColor VisColor; // Free chunk. if( CurrentChunk->bIsAvailable ) { NumFreeChunks++; FreeSize += CurrentChunk->Size; VisColor = FColor(0,255,0); } // Allocated chunk. else { NumUsedChunks++; UsedSize += CurrentChunk->Size; // Slightly alternate coloration to also visualize allocation sizes. if( NumUsedChunks % 2 == 0 ) { VisColor = FColor(255,0,0); } else { VisColor = FColor(192,0,0); } } for( INT i=0; i<(CurrentChunk->Size/AllocationAlignment); i++ ) { AllocationVisualization(VisIndex++) = VisColor; } CurrentChunk = CurrentChunk->NextChunk; } check(UsedSize == AllocatedMemorySize); check(FreeSize == AvailableMemorySize); // Write out bitmap for visualization of fragmentation and allocation patterns. appCreateBitmap( TEXT("..\\..\\Binaries\\TextureMemory"), Dimension, Dimension, AllocationVisualization.GetTypedData() ); Ar.Logf( TEXT("BestFitAllocator: Allocated %i KByte in %i chunks, leaving %i KByte in %i chunks."), UsedSize / 1024, NumUsedChunks, FreeSize / 1024, NumFreeChunks ); Ar.Logf( TEXT("BestFitAllocator: %5.2f ms in allocator"), TimeSpentInAllocator * 1000 ); }
/** * Dumps capture stack trace summary to the passed in log. */ void FScriptStackTracker::DumpStackTraces( int32 StackThreshold, FOutputDevice& Ar ) { // Avoid distorting results while we log them. check( !bAvoidCapturing ); bAvoidCapturing = true; // Make a copy as sorting causes index mismatch with TMap otherwise. TArray<FCallStack> SortedCallStacks = CallStacks; // Compare function, sorting callstack by stack count in descending order. struct FCompareStackCount { FORCEINLINE bool operator()( const FCallStack& A, const FCallStack& B ) const { return B.StackCount < A.StackCount; } }; // Sort callstacks in descending order by stack count. SortedCallStacks.Sort( FCompareStackCount() ); // Iterate over each callstack to get total stack count. uint64 TotalStackCount = 0; for( int32 CallStackIndex=0; CallStackIndex<SortedCallStacks.Num(); CallStackIndex++ ) { const FCallStack& CallStack = SortedCallStacks[CallStackIndex]; TotalStackCount += CallStack.StackCount; } // Calculate the number of frames we captured. int32 FramesCaptured = 0; if( bIsEnabled ) { FramesCaptured = GFrameCounter - StartFrameCounter; } else { FramesCaptured = StopFrameCounter - StartFrameCounter; } // Log quick summary as we don't log each individual so totals in CSV won't represent real totals. Ar.Logf(TEXT("Captured %i unique callstacks totalling %i function calls over %i frames, averaging %5.2f calls/frame"), SortedCallStacks.Num(), (int32)TotalStackCount, FramesCaptured, (float) TotalStackCount / FramesCaptured); // Iterate over each callstack and write out info in human readable form in CSV format for( int32 CallStackIndex=0; CallStackIndex<SortedCallStacks.Num(); CallStackIndex++ ) { const FCallStack& CallStack = SortedCallStacks[CallStackIndex]; // Avoid log spam by only logging above threshold. if( CallStack.StackCount > StackThreshold ) { // First row is stack count. FString CallStackString = FString::FromInt((int32)CallStack.StackCount); CallStackString += LINE_TERMINATOR; CallStackString += CallStack.StackTrace; // Finally log with ',' prefix so "Log:" can easily be discarded as row in Excel. Ar.Logf(TEXT(",%s"),*CallStackString); } } // Done logging. bAvoidCapturing = false; }
void UExporter::EmitEndObject( FOutputDevice& Ar ) { if ( bEnableDebugBrackets ) { Ar.Logf(TEXT("%s}%s"), FCString::Spc(TextIndent), LINE_TERMINATOR); } Ar.Logf( TEXT("%sEnd Object\r\n"), FCString::Spc(TextIndent) ); }
void UK2Node_EditablePinBase::ExportCustomProperties(FOutputDevice& Out, uint32 Indent) { for (int32 PinIndex = 0; PinIndex < UserDefinedPins.Num(); ++PinIndex) { const FUserPinInfo& PinInfo = *UserDefinedPins[PinIndex].Get(); Out.Logf( TEXT("%sCustomProperties UserDefinedPin "), FCString::Spc(Indent)); Out.Logf( TEXT("Name=%s "), *PinInfo.PinName); Out.Logf( TEXT("IsArray=%s "), (PinInfo.PinType.bIsArray ? TEXT("1") : TEXT("0"))); Out.Logf( TEXT("IsReference=%s "), (PinInfo.PinType.bIsReference ? TEXT("1") : TEXT("0"))); if (PinInfo.PinType.PinCategory.Len() > 0) { Out.Logf( TEXT("Category=%s "), *PinInfo.PinType.PinCategory); } if (PinInfo.PinType.PinSubCategory.Len() > 0) { Out.Logf( TEXT("SubCategory=%s "), *PinInfo.PinType.PinSubCategory); } if (PinInfo.PinType.PinSubCategoryObject.IsValid()) { Out.Logf( TEXT("SubCategoryObject=%s "), *PinInfo.PinType.PinSubCategoryObject.Get()->GetPathName()); } if (PinInfo.PinDefaultValue.Len() > 0) { Out.Logf( TEXT("DefaultValue=%s "), *PinInfo.PinDefaultValue); } Out.Logf( TEXT("\r\n")); } }
/** * Dumps capture stack trace summary to the passed in log. */ void FScriptStackTracker::DumpStackTraces( INT StackThreshold, FOutputDevice& Ar ) { // Avoid distorting results while we log them. check( !bAvoidCapturing ); bAvoidCapturing = TRUE; // Make a copy as sorting causes index mismatch with TMap otherwise. TArray<FCallStack> SortedCallStacks = CallStacks; // Sort callstacks in descending order by stack count. Sort<USE_COMPARE_CONSTREF(FCallStack,StackTracker)>( SortedCallStacks.GetTypedData(), SortedCallStacks.Num() ); // Iterate over each callstack to get total stack count. QWORD TotalStackCount = 0; for( INT CallStackIndex=0; CallStackIndex<SortedCallStacks.Num(); CallStackIndex++ ) { const FCallStack& CallStack = SortedCallStacks(CallStackIndex); TotalStackCount += CallStack.StackCount; } // Calculate the number of frames we captured. INT FramesCaptured = 0; if( bIsEnabled ) { FramesCaptured = GFrameCounter - StartFrameCounter; } else { FramesCaptured = StopFrameCounter - StartFrameCounter; } // Log quick summary as we don't log each individual so totals in CSV won't represent real totals. Ar.Logf(TEXT("Captured %i unique callstacks totalling %i function calls over %i frames, averaging %5.2f calls/frame"), SortedCallStacks.Num(), (int)TotalStackCount, FramesCaptured, (FLOAT) TotalStackCount / FramesCaptured); // Iterate over each callstack and write out info in human readable form in CSV format for( INT CallStackIndex=0; CallStackIndex<SortedCallStacks.Num(); CallStackIndex++ ) { const FCallStack& CallStack = SortedCallStacks(CallStackIndex); // Avoid log spam by only logging above threshold. if( CallStack.StackCount > StackThreshold ) { // First row is stack count. FString CallStackString = appItoa(CallStack.StackCount); CallStackString += LINE_TERMINATOR; CallStackString += CallStack.StackTrace; // Finally log with ',' prefix so "Log:" can easily be discarded as row in Excel. Ar.Logf(TEXT(",%s"),*CallStackString); } } // Done logging. bAvoidCapturing = FALSE; }
void FHttpManager::DumpRequests(FOutputDevice& Ar) const { FScopeLock ScopeLock(&RequestLock); Ar.Logf(TEXT("------- (%d) Http Requests"), Requests.Num()); for (const TSharedRef<IHttpRequest>& Request : Requests) { Ar.Logf(TEXT(" verb=[%s] url=[%s] status=%s"), *Request->GetVerb(), *Request->GetURL(), EHttpRequestStatus::ToString(Request->GetStatus())); } }
/** * Outputs the contents of the ObjectMap to the specified output device. */ void FTransaction::DumpObjectMap(FOutputDevice& Ar) const { Ar.Logf( TEXT("===== DumpObjectMap %s ==== "), *Title.ToString() ); for ( ObjectMapType::TConstIterator It(ObjectMap) ; It ; ++It ) { const UObject* CurrentObject = It.Key(); const int32 SaveCount = It.Value(); Ar.Logf( TEXT("%i\t: %s"), SaveCount, *CurrentObject->GetPathName() ); } Ar.Logf( TEXT("=== EndDumpObjectMap %s === "), *Title.ToString() ); }
bool UIpNetDriver::HandleSocketsCommand( const TCHAR* Cmd, FOutputDevice& Ar, UWorld* InWorld ) { Ar.Logf(TEXT("")); if (Socket != NULL) { TSharedRef<FInternetAddr> LocalAddr = GetSocketSubsystem()->CreateInternetAddr(); Socket->GetAddress(*LocalAddr); Ar.Logf(TEXT("%s Socket: %s"), *GetDescription(), *LocalAddr->ToString(true)); } else { Ar.Logf(TEXT("%s Socket: null"), *GetDescription()); } return UNetDriver::Exec( InWorld, TEXT("SOCKETS"),Ar); }
bool FOSVRHMD::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar) { if (FParse::Command(&Cmd, TEXT("STEREO"))) { if (FParse::Command(&Cmd, TEXT("ON"))) { if (!IsHMDEnabled()) { Ar.Logf(TEXT("HMD is disabled. Use 'hmd enable' to re-enable it.")); } EnableStereo(true); return true; } else if (FParse::Command(&Cmd, TEXT("OFF"))) { EnableStereo(false); return true; } } else if (FParse::Command(&Cmd, TEXT("HMD"))) { if (FParse::Command(&Cmd, TEXT("ENABLE"))) { EnableHMD(true); return true; } else if (FParse::Command(&Cmd, TEXT("DISABLE"))) { EnableHMD(false); return true; } } else if (FParse::Command(&Cmd, TEXT("UNCAPFPS"))) { GEngine->bSmoothFrameRate = false; return true; } else if (FParse::Command(&Cmd, TEXT("HEADTRACKING"))) { FString val; if (FParse::Value(Cmd, TEXT("SOURCE="), val)) { EnablePositionalTracking(false); //OSVRInterfaceName = val; EnablePositionalTracking(true); } if (FParse::Command(&Cmd, TEXT("ENABLE"))) { EnablePositionalTracking(true); return true; } else if (FParse::Command(&Cmd, TEXT("DISABLE"))) { EnablePositionalTracking(false); return true; } } return false; }
bool UGameEngine::HandleMinimizeCommand( const TCHAR *Cmd, FOutputDevice &Ar ) { Ar.Log( TEXT("Minimize by request") ); FPlatformMisc::RequestMinimize(); return true; }
bool UGameEngine::HandleExitCommand( const TCHAR* Cmd, FOutputDevice& Ar ) { Ar.Log( TEXT("Closing by request") ); FGameDelegates::Get().GetExitCommandDelegate().Broadcast(); FPlatformMisc::RequestExit( 0 ); return true; }
/** * Exec handler implementation. * * @param InWorld World context * @param Cmd Command to parse * @param Ar Output device to log to * * @return true if command was handled, false otherwise */ bool FSystemSettings::Exec( UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar ) { FSystemSettingsData OldSystemSettings = *this; // Keep track whether the command was handled or not. bool bHandledCommand = false; if( FParse::Command(&Cmd,TEXT("SCALE")) ) { // Some of these settings are used in both threads so we need to stop the rendering thread before changing them. FlushRenderingCommands(); if( FParse::Command(&Cmd,TEXT("LOWEND")) ) { bHandledCommand = HandleLowendCommand( Cmd, Ar ); } else if( FParse::Command(&Cmd,TEXT("HIGHEND")) ) { bHandledCommand = HandleHighendCommand( Cmd, Ar ); } if (!bHandledCommand) { Ar.Logf(TEXT("Unrecognized system setting (note that console variables can be set much easier)")); } else { // Write the new settings to the INI. SaveToIni(); } } return bHandledCommand; }
/** * The unsynchronized version of FlushThreadedLogs. * Assumes that the caller holds a lock on SynchronizationObject. */ void FOutputDeviceRedirector::UnsynchronizedFlushThreadedLogs( bool bUseAllDevices ) { for(int32 LineIndex = 0;LineIndex < BufferedLines.Num();LineIndex++) { FBufferedLine BufferedLine = BufferedLines[LineIndex]; for( int32 OutputDeviceIndex=0; OutputDeviceIndex<OutputDevices.Num(); OutputDeviceIndex++ ) { FOutputDevice* OutputDevice = OutputDevices[OutputDeviceIndex]; if( OutputDevice->CanBeUsedOnAnyThread() || bUseAllDevices ) { OutputDevice->Serialize( *BufferedLine.Data, BufferedLine.Verbosity, BufferedLine.Category, BufferedLine.Time ); } } } BufferedLines.Empty(); }
void FPakPlatformFile::HandlePakListCommand(const TCHAR* Cmd, FOutputDevice& Ar) { TArray<FPakListEntry> Paks; GetMountedPaks(Paks); for (auto Pak : Paks) { Ar.Logf(TEXT("%s"), *Pak.PakFile->GetFilename()); } }
virtual bool Exec( class UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar ) { if (FParse::Command(&Cmd, TEXT("TOGGLESTATECACHE"))) { GD3D11SkipStateCaching = !GD3D11SkipStateCaching; Ar.Log(FString::Printf(TEXT("D3D11 State Caching: %s"), GD3D11SkipStateCaching ? TEXT("OFF") : TEXT("ON"))); return true; } return false; }
static void DumpRHIMemory(FOutputDevice& OutputDevice) { TArray<FStatMessage> Stats; GetPermanentStats(Stats); FName NAME_STATGROUP_RHI(FStatGroup_STATGROUP_RHI::GetGroupName()); OutputDevice.Logf(TEXT("RHI resource memory (not tracked by our allocator)")); int64 TotalMemory = 0; for (int32 Index = 0; Index < Stats.Num(); Index++) { FStatMessage const& Meta = Stats[Index]; FName LastGroup = Meta.NameAndInfo.GetGroupName(); if (LastGroup == NAME_STATGROUP_RHI && Meta.NameAndInfo.GetFlag(EStatMetaFlags::IsMemory)) { OutputDevice.Logf(TEXT("%s"), *FStatsUtils::DebugPrint(Meta)); TotalMemory += Meta.GetValue_int64(); } } OutputDevice.Logf(TEXT("%.3fMB total"), TotalMemory / 1024.f / 1024.f); }
void FOutputDeviceRedirector::PanicFlushThreadedLogs() { SCOPE_CYCLE_COUNTER(STAT_FlushThreadedLogs); // Acquire a lock on SynchronizationObject and call the unsynchronized worker function. FScopeLock ScopeLock( &SynchronizationObject ); // Flush threaded logs, but use the safe version. UnsynchronizedFlushThreadedLogs( false ); // Flush devices. for (int32 OutputDeviceIndex = 0; OutputDeviceIndex<OutputDevices.Num(); OutputDeviceIndex++) { FOutputDevice* OutputDevice = OutputDevices[OutputDeviceIndex]; if (OutputDevice->CanBeUsedOnAnyThread()) { OutputDevice->Flush(); } } BufferedLines.Empty(); }
// Disassemble all functions in any classes that have matching names. void FKismetBytecodeDisassembler::DisassembleAllFunctionsInClasses(FOutputDevice& Ar, const FString& ClassnameSubstring) { FKismetBytecodeDisassembler Disasm(Ar); for (TObjectIterator<UClass> ClassIter; ClassIter; ++ClassIter) { UClass* Class = *ClassIter; FString ClassName = Class->GetName(); if (FCString::Strfind(*ClassName, *ClassnameSubstring)) { Ar.Logf(TEXT("Processing class %s"), *ClassName); for (TFieldIterator<UFunction> FunctionIter(Class, EFieldIteratorFlags::ExcludeSuper); FunctionIter; ++FunctionIter) { UFunction* Function = *FunctionIter; FString FunctionName = Function->GetName(); Ar.Logf(TEXT(" Processing function %s (%d bytes)"), *FunctionName, Function->Script.Num()); Disasm.DisassembleStructure(Function); Ar.Logf(TEXT("")); } Ar.Logf(TEXT("")); Ar.Logf(TEXT("-----------")); Ar.Logf(TEXT("")); } } }
void UExporter::EmitBeginObject( FOutputDevice& Ar, UObject* Obj, uint32 PortFlags ) { check(Obj); // figure out how to export bool bIsExportingDefaultObject = Obj->HasAnyFlags(RF_ClassDefaultObject) || Obj->GetArchetype()->HasAnyFlags(RF_ClassDefaultObject); // start outputting the string for the Begin Object line Ar.Logf(TEXT("%sBegin Object"), FCString::Spc(TextIndent)); if (!(PortFlags & PPF_SeparateDefine)) { Ar.Logf(TEXT(" Class=%s"), *Obj->GetClass()->GetName()); } // always need a name, adding "" for space handling Ar.Logf(TEXT(" Name=\"%s\""), *Obj->GetName()); if (!(PortFlags & PPF_SeparateDefine)) { // do we want the archetype string? if (!bIsExportingDefaultObject) { Ar.Logf(TEXT(" Archetype=%s'%s'"), *Obj->GetArchetype()->GetClass()->GetName(), *Obj->GetArchetype()->GetPathName()); } } // end in a return Ar.Logf(TEXT("\r\n")); if ( bEnableDebugBrackets ) { Ar.Logf(TEXT("%s{%s"), FCString::Spc(TextIndent), LINE_TERMINATOR); } }
void FName::DisplayHash( FOutputDevice& Ar ) { int32 UsedBins=0, NameCount=0, MemUsed = 0; for( int32 i=0; i<ARRAY_COUNT(NameHash); i++ ) { if( NameHash[i] != NULL ) UsedBins++; for( FNameEntry *Hash = NameHash[i]; Hash; Hash=Hash->HashNext ) { NameCount++; // Count how much memory this entry is using MemUsed += FNameEntry::GetSize( Hash->GetNameLength(), Hash->IsWide() ); } } Ar.Logf( TEXT("Hash: %i names, %i/%i hash bins, Mem in bytes %i"), NameCount, UsedBins, ARRAY_COUNT(NameHash), MemUsed); }
void FObjectMemoryAnalyzer::PrintSubObjects(FOutputDevice& Ar, const FString& Indent, UObject* Parent, uint32 PrintFlags) { TArray<UObject*> ReferencedObjects; GetReferencedObjects(Parent, ReferencedObjects); for( int32 ObjIndex = 0; ObjIndex < ReferencedObjects.Num(); ObjIndex++ ) { UObject* SubObj = ReferencedObjects[ObjIndex]; const FObjectMemoryUsage& Annotation = GetObjectMemoryUsage(SubObj); if (!Annotation.IsRoot()) { Ar.Logf( TEXT("%-100s %-10d %-10d %-10d %-10d"), *FString::Printf(TEXT("%s%s %s"), *Indent, *SubObj->GetClass()->GetName(), *SubObj->GetName()), (int32)Annotation.InclusiveMemoryUsage, (int32)Annotation.ExclusiveMemoryUsage, (int32)(Annotation.InclusiveResourceSize/1024), (int32)(Annotation.ExclusiveResourceSize/1024) ); if (!!(PrintFlags&EPrintFlags::PrintReferencer)) { for (int32 i=0; i < Annotation.NonRootReferencer.Num(); ++i) { Ar.Logf(TEXT("%s >> NonRootRef: %s"), *Indent, *Annotation.NonRootReferencer[i]->GetName()); } for (int32 i=0; i < Annotation.RootReferencer.Num(); ++i) { Ar.Logf(TEXT("%s >> RootRef: %s"), *Indent, *Annotation.RootReferencer[i]->GetName()); } } if (!!(PrintFlags&EPrintFlags::PrintReferences)) { PrintSubObjects(Ar, Indent + TEXT(" -> "), SubObj, PrintFlags); } } } }
/** * Prints the subtitle associated with the SoundWave to the console */ void USoundWave::LogSubtitle( FOutputDevice& Ar ) { FString Subtitle = ""; for( int32 i = 0; i < Subtitles.Num(); i++ ) { Subtitle += Subtitles[ i ].Text.ToString(); } if( Subtitle.Len() == 0 ) { Subtitle = SpokenText; } if( Subtitle.Len() == 0 ) { Subtitle = "<NO SUBTITLE>"; } Ar.Logf( TEXT( "Subtitle: %s" ), *Subtitle ); #if WITH_EDITORONLY_DATA Ar.Logf( TEXT( "Comment: %s" ), *Comment ); #endif // WITH_EDITORONLY_DATA Ar.Logf( bMature ? TEXT( "Mature: Yes" ) : TEXT( "Mature: No" ) ); }
/** * Process a "[cat] only" string command to the logging suppression system * @param CmdString, string to process * @return true if CmdString was a "[cat] only" string command, false otherwise */ bool ProcessLogOnly(const FString& CmdString, FOutputDevice& Ar) { TArray<FString> CommandParts; CmdString.ParseIntoArrayWS(CommandParts); if (CommandParts.Num() <= 1) { return false; } static FName NAME_Only(TEXT("only")); if (NAME_Only != FName(*CommandParts[1])) { return false; } FName LogCategory = FName(*CommandParts[0]); static const FString OffString = FString(" off"); static const FString OnString = FString(" Verbose"); for (auto It : Associations) { FName Name = It.Value; if (Name == LogCategory) { ProcessCmdString(Name.ToString() + OnString); FLogCategoryBase* Verb = It.Key; Ar.Logf(TEXT("%s is now %s"), *CommandParts[0], FOutputDevice::VerbosityToString(Verb ? ELogVerbosity::Type(Verb->Verbosity) : ELogVerbosity::Verbose)); } else { ProcessCmdString(Name.ToString() + OffString); } } Ar.Logf(TEXT("Disabling other logs finished")); return true; }
bool VZipFileReader::Close() { guard(VZipFileReader::Close); if (rest_read_uncompressed == 0) { if (Crc32 != Info.crc) { bError = true; Error->Log("Bad CRC"); } } if (stream_initialised) { inflateEnd(&stream); } stream_initialised = false; return !bError; unguard; }
bool UGameInstance::HandleOpenCommand(const TCHAR* Cmd, FOutputDevice& Ar, UWorld* InWorld) { check(WorldContext && WorldContext->World() == InWorld); UEngine* const Engine = GetEngine(); FURL TestURL(&WorldContext->LastURL, Cmd, TRAVEL_Absolute); if (TestURL.IsLocalInternal()) { // make sure the file exists if we are opening a local file if (!Engine->MakeSureMapNameIsValid(TestURL.Map)) { Ar.Logf(TEXT("ERROR: The map '%s' does not exist."), *TestURL.Map); return true; } } Engine->SetClientTravel(InWorld, Cmd, TRAVEL_Absolute); return true; }
/** After the stack tracker reports a given stack trace, it calls this function * which appends data particular to line checks */ static void LineCheckReportFn(const FStackTracker::FCallStack& CallStack, uint64 TotalStackCount, FOutputDevice& Ar) { //Output to a csv file any relevant data LineCheckTracker::FLineCheckData* const LCData = static_cast<LineCheckTracker::FLineCheckData*>(CallStack.UserData); if (LCData) { FString UserOutput = LINE_TERMINATOR TEXT(",,,"); UserOutput += (LCData->IsNonZeroExtent ? TEXT( "NonZeroExtent") : TEXT("ZeroExtent")); for (TMap<const FName, LineCheckTracker::FLineCheckData::LineCheckObj>::TConstIterator It(LCData->LineCheckObjsMap); It; ++It) { UserOutput += LINE_TERMINATOR TEXT(",,,"); const LineCheckTracker::FLineCheckData::LineCheckObj &CurObj = It.Value(); UserOutput += FString::Printf(TEXT("%s (%d) : %s"), *CurObj.ObjectName.ToString(), CurObj.Count, *CurObj.DetailedInfo); } UserOutput += LINE_TERMINATOR TEXT(",,,"); Ar.Log(*UserOutput); } }
bool UGameEngine::HandleExitCommand( const TCHAR* Cmd, FOutputDevice& Ar ) { for (int32 WorldIndex = 0; WorldIndex < WorldList.Num(); ++WorldIndex) { UWorld* const World = WorldList[WorldIndex].World(); AGameMode* const GameMode = World->GetAuthGameMode(); if (GameMode) { GameMode->GameEnding(); } // Cancel any pending connection to a server CancelPending(WorldList[WorldIndex]); // Shut down any existing game connections ShutdownWorldNetDriver(World); } Ar.Log( TEXT("Closing by request") ); FPlatformMisc::RequestExit( 0 ); return true; }