本文整理汇总了C++中FTimespan::GetTotalSeconds方法的典型用法代码示例。如果您正苦于以下问题:C++ FTimespan::GetTotalSeconds方法的具体用法?C++ FTimespan::GetTotalSeconds怎么用?C++ FTimespan::GetTotalSeconds使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FTimespan
的用法示例。
在下文中一共展示了FTimespan::GetTotalSeconds方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GetFileAgeSeconds
double FFileManagerGeneric::GetFileAgeSeconds( const TCHAR* Filename )
{
// make sure it exists
if (!GetLowLevel().FileExists(Filename))
{
return -1.0;
}
// get difference in time between now (UTC) and the filetime
FTimespan Age = FDateTime::UtcNow() - GetTimeStamp(Filename);
return Age.GetTotalSeconds();
}
示例2: timeUntilRespawn
float AFPSGPlayerController::timeUntilRespawn()
{
float timeToRespawn = 0.0f;
if (!isAlive)
{
if (timeOfDeath != FDateTime::MinValue())
{
FTimespan timeSinceDeath = FDateTime::Now() - timeOfDeath;
timeToRespawn = respawnTime - static_cast<float>(timeSinceDeath.GetTotalSeconds());
}
}
return timeToRespawn;
}
示例3: select
EIPv6SocketInternalState::Return FSocketBSDIPv6::HasState(EIPv6SocketInternalState::Param State, FTimespan WaitTime)
{
#if PLATFORM_HAS_BSD_SOCKET_FEATURE_SELECT
// convert WaitTime to a timeval
timeval Time;
Time.tv_sec = (int32)WaitTime.GetTotalSeconds();
Time.tv_usec = WaitTime.GetMilliseconds() * 1000;
fd_set SocketSet;
// Set up the socket sets we are interested in (just this one)
FD_ZERO(&SocketSet);
FD_SET(Socket, &SocketSet);
// Check the status of the state
int32 SelectStatus = 0;
switch (State)
{
case EIPv6SocketInternalState::CanRead:
SelectStatus = select(Socket + 1, &SocketSet, NULL, NULL, &Time);
break;
case EIPv6SocketInternalState::CanWrite:
SelectStatus = select(Socket + 1, NULL, &SocketSet, NULL, &Time);
break;
case EIPv6SocketInternalState::HasError:
SelectStatus = select(Socket + 1, NULL, NULL, &SocketSet, &Time);
break;
}
// if the select returns a positive number, the socket had the state, 0 means didn't have it, and negative is API error condition (not socket's error state)
return SelectStatus > 0 ? EIPv6SocketInternalState::Yes :
SelectStatus == 0 ? EIPv6SocketInternalState::No :
EIPv6SocketInternalState::EncounteredError;
#else
UE_LOG(LogSockets, Fatal, TEXT("This platform doesn't support select(), but FSocketBSD::HasState was not overridden"));
return EIPv6SocketInternalState::EncounteredError;
#endif
}
示例4: atlasSampleTL
//.........这里部分代码省略.........
const FIntPoint atlasSampleTL(sliceCenterPixelX + FMath::Clamp(slicePixelX , -StripWidth/2, StripWidth/2), sliceCenterPixelY + FMath::Clamp(slicePixelY , -StripHeight/2, StripHeight/2));
const FIntPoint atlasSampleTR(sliceCenterPixelX + FMath::Clamp(slicePixelX + 1, -StripWidth/2, StripWidth/2), sliceCenterPixelY + FMath::Clamp(slicePixelY , -StripHeight/2, StripHeight/2));
const FIntPoint atlasSampleBL(sliceCenterPixelX + FMath::Clamp(slicePixelX , -StripWidth/2, StripWidth/2), sliceCenterPixelY + FMath::Clamp(slicePixelY + 1, -StripHeight/2, StripHeight/2));
const FIntPoint atlasSampleBR(sliceCenterPixelX + FMath::Clamp(slicePixelX + 1, -StripWidth/2, StripWidth/2), sliceCenterPixelY + FMath::Clamp(slicePixelY + 1, -StripHeight/2, StripHeight/2));
const FColor pixelColorTL = SurfaceData[atlasSampleTL.Y * UnprojectedAtlasWidth + atlasSampleTL.X];
const FColor pixelColorTR = SurfaceData[atlasSampleTR.Y * UnprojectedAtlasWidth + atlasSampleTR.X];
const FColor pixelColorBL = SurfaceData[atlasSampleBL.Y * UnprojectedAtlasWidth + atlasSampleBL.X];
const FColor pixelColorBR = SurfaceData[atlasSampleBR.Y * UnprojectedAtlasWidth + atlasSampleBR.X];
const float fracX = FMath::Frac(dbgMatchCaptureSliceFovToAtlasSliceFov ? sliceU * StripWidth : sliceU * CaptureWidth);
const float fracY = FMath::Frac(dbgMatchCaptureSliceFovToAtlasSliceFov ? sliceV * StripHeight : sliceV * CaptureHeight);
//Reinterpret as linear (a.k.a dont apply srgb inversion)
slicePixelSample = FMath::BiLerp(
pixelColorTL.ReinterpretAsLinear(), pixelColorTR.ReinterpretAsLinear(),
pixelColorBL.ReinterpretAsLinear(), pixelColorBR.ReinterpretAsLinear(),
fracX, fracY);
}
else
{
const int32 sliceCenterPixelX = (sliceXIndex + 0.5f) * StripWidth;
const int32 sliceCenterPixelY = (sliceYIndex + 0.5f) * StripHeight;
const int32 atlasSampleX = sliceCenterPixelX + slicePixelX;
const int32 atlasSampleY = sliceCenterPixelY + slicePixelY;
slicePixelSample = SurfaceData[atlasSampleY * UnprojectedAtlasWidth + atlasSampleX].ReinterpretAsLinear();
}
samplePixelAccum += slicePixelSample;
////Output color map of projections
//const FColor debugEquiColors[12] = {
// FColor(205, 180, 76),
// FColor(190, 88, 202),
// FColor(127, 185, 194),
// FColor(90, 54, 47),
// FColor(197, 88, 53),
// FColor(197, 75, 124),
// FColor(130, 208, 72),
// FColor(136, 211, 153),
// FColor(126, 130, 207),
// FColor(83, 107, 59),
// FColor(200, 160, 157),
// FColor(80, 66, 106)
//};
//samplePixelAccum = ssPattern.numSamples * debugEquiColors[sliceYIndex * 4 + sliceXIndex];
}
SphericalAtlas[y * SphericalAtlasWidth + x] = (samplePixelAccum / ssPattern.numSamples).Quantize();
// Force alpha value
if (bForceAlpha)
{
SphericalAtlas[y * SphericalAtlasWidth + x].A = 255;
}
}
}
//Blit the first column into the last column to make the stereo image seamless at theta=360
for (int32 y = 0; y < SphericalAtlasHeight; y++)
{
SphericalAtlas[y * SphericalAtlasWidth + (SphericalAtlasWidth - 1)] = SphericalAtlas[y * SphericalAtlasWidth + 0];
}
const FTimespan SamplingDuration = FDateTime::UtcNow() - SamplingStartTime;
UE_LOG(LogStereoPanorama, Log, TEXT("...done! Duration: %g seconds"), SamplingDuration.GetTotalSeconds());
}
// Generate name
FString FrameString = FString::Printf( TEXT( "%s_%05d.png" ), *Folder, CurrentFrameCount );
FString AtlasName = OutputDir / Timestamp / FrameString;
UE_LOG( LogStereoPanorama, Log, TEXT( "Writing atlas: %s" ), *AtlasName );
// Write out PNG
//TODO: ikrimae: Use threads to write out the images for performance
IImageWrapperPtr ImageWrapper = ImageWrapperModule.CreateImageWrapper( EImageFormat::PNG );
ImageWrapper->SetRaw(SphericalAtlas.GetData(), SphericalAtlas.GetAllocatedSize(), SphericalAtlasWidth, SphericalAtlasHeight, ERGBFormat::BGRA, 8);
const TArray<uint8>& PNGData = ImageWrapper->GetCompressed(100);
FFileHelper::SaveArrayToFile( PNGData, *AtlasName );
if (FStereoPanoramaManager::GenerateDebugImages->GetInt() != 0)
{
FString FrameStringUnprojected = FString::Printf(TEXT("%s_%05d_Unprojected.png"), *Folder, CurrentFrameCount);
FString AtlasNameUnprojected = OutputDir / Timestamp / FrameStringUnprojected;
ImageWrapper->SetRaw(SurfaceData.GetData(), SurfaceData.GetAllocatedSize(), UnprojectedAtlasWidth, UnprojectedAtlasHeight, ERGBFormat::BGRA, 8);
const TArray<uint8>& PNGDataUnprojected = ImageWrapper->GetCompressed(100);
FFileHelper::SaveArrayToFile(PNGData, *AtlasNameUnprojected);
}
ImageWrapper.Reset();
UE_LOG( LogStereoPanorama, Log, TEXT( " ... done!" ), *AtlasName );
return SphericalAtlas;
}
示例5: GetTotalSeconds
float UKismetMathLibrary::GetTotalSeconds( FTimespan A )
{
return A.GetTotalSeconds();
}
示例6: SetupCallbacks
void USocketIOClientComponent::SetupCallbacks()
{
//Sync current connected state
bIsConnected = NativeClient->bIsConnected;
if (bIsConnected)
{
SessionId = NativeClient->SessionId;
AddressAndPort = NativeClient->AddressAndPort;
}
NativeClient->OnConnectedCallback = [this](const FString& InSessionId)
{
FLambdaRunnable::RunShortLambdaOnGameThread([this, InSessionId]
{
if (this)
{
bIsConnected = true;
SessionId = InSessionId;
OnConnected.Broadcast(SessionId, bIsHavingConnectionProblems);
bIsHavingConnectionProblems = false;
}
});
};
const FSIOCCloseEventSignature OnDisconnectedSafe = OnDisconnected;
NativeClient->OnDisconnectedCallback = [OnDisconnectedSafe, this](const ESIOConnectionCloseReason Reason)
{
FLambdaRunnable::RunShortLambdaOnGameThread([OnDisconnectedSafe, this, Reason]
{
if (this && OnDisconnectedSafe.IsBound())
{
bIsConnected = false;
OnDisconnectedSafe.Broadcast(Reason);
}
});
};
NativeClient->OnNamespaceConnectedCallback = [this](const FString& Namespace)
{
FLambdaRunnable::RunShortLambdaOnGameThread([this, Namespace]
{
if (this && OnSocketNamespaceConnected.IsBound())
{
OnSocketNamespaceConnected.Broadcast(Namespace);
}
});
};
const FSIOCSocketEventSignature OnSocketNamespaceDisconnectedSafe = OnSocketNamespaceDisconnected;
NativeClient->OnNamespaceDisconnectedCallback = [this, OnSocketNamespaceDisconnectedSafe](const FString& Namespace)
{
FLambdaRunnable::RunShortLambdaOnGameThread([OnSocketNamespaceDisconnectedSafe, this, Namespace]
{
if (this && OnSocketNamespaceDisconnectedSafe.IsBound())
{
OnSocketNamespaceDisconnectedSafe.Broadcast(Namespace);
}
});
};
NativeClient->OnReconnectionCallback = [this](const uint32 AttemptCount, const uint32 DelayInMs)
{
FLambdaRunnable::RunShortLambdaOnGameThread([this, AttemptCount, DelayInMs]
{
//First time we know about this problem?
if (!bIsHavingConnectionProblems)
{
TimeWhenConnectionProblemsStarted = FDateTime::Now();
bIsHavingConnectionProblems = true;
}
FTimespan Difference = FDateTime::Now() - TimeWhenConnectionProblemsStarted;
float ElapsedInSec = Difference.GetTotalSeconds();
if (ReconnectionTimeout > 0 && ElapsedInSec>ReconnectionTimeout)
{
//Let's stop trying and disconnect if we're using timeouts
Disconnect();
}
if (this && OnConnectionProblems.IsBound())
{
OnConnectionProblems.Broadcast(AttemptCount, DelayInMs, ElapsedInSec);
}
});
};
NativeClient->OnFailCallback = [this]()
{
FLambdaRunnable::RunShortLambdaOnGameThread([this]
{
OnFail.Broadcast();
});
};
}
示例7: StartCheckInternal
UUpdateManager::EUpdateStartResult UUpdateManager::StartCheckInternal(bool bInCheckHotfixOnly)
{
EUpdateStartResult Result = EUpdateStartResult::None;
if (!ChecksEnabled())
{
UE_LOG(LogHotfixManager, Display, TEXT("Update checks disabled!"));
bInitialUpdateFinished = true;
auto StartDelegate = [this]()
{
CheckComplete(EUpdateCompletionStatus::UpdateSuccess_NoChange);
};
DelayResponse(StartDelegate, 0.1f);
return Result;
}
if (CurrentUpdateState == EUpdateState::UpdateIdle ||
CurrentUpdateState == EUpdateState::UpdatePending ||
CurrentUpdateState == EUpdateState::UpdateComplete)
{
bCheckHotfixAvailabilityOnly = bInCheckHotfixOnly;
// Immediately move into a pending state so the UI state trigger fires
SetUpdateState(EUpdateState::UpdatePending);
const EUpdateCompletionStatus LastResult = LastCompletionResult[bCheckHotfixAvailabilityOnly];
const FTimespan DeltaTime = FDateTime::UtcNow() - LastUpdateCheck[bCheckHotfixAvailabilityOnly];
const bool bForceCheck = LastResult == EUpdateCompletionStatus::UpdateUnknown ||
LastResult == EUpdateCompletionStatus::UpdateFailure_PatchCheck ||
LastResult == EUpdateCompletionStatus::UpdateFailure_HotfixCheck ||
LastResult == EUpdateCompletionStatus::UpdateFailure_NotLoggedIn;
static double CacheTimer = UPDATE_CHECK_SECONDS;
const double TimeSinceCheck = DeltaTime.GetTotalSeconds();
if (bForceCheck || TimeSinceCheck >= CacheTimer)
{
auto StartDelegate = [this]()
{
// Check for a patch first, then hotfix application
StartPatchCheck();
};
// Give the UI state widget a chance to start listening for delegates
DelayResponse(StartDelegate, 0.2f);
Result = EUpdateStartResult::UpdateStarted;
}
else
{
UE_LOG(LogHotfixManager, Display, TEXT("Returning cached update result %d"), (int32)LastResult);
auto StartDelegate = [this, LastResult]()
{
CheckComplete(LastResult, false);
};
DelayResponse(StartDelegate, 0.1f);
Result = EUpdateStartResult::UpdateCached;
}
}
else
{
UE_LOG(LogHotfixManager, Display, TEXT("Update already in progress"));
}
return Result;
}
示例8: ProcessExecutionRequest
void UHTNPlannerComponent::ProcessExecutionRequest()
{
bRequestedExecutionUpdate = false;
if(!IsRegistered())
{
// it shouldn't be called, component is no longer valid
return;
}
if(bIsPaused)
{
UE_VLOG(GetOwner(), LogHTNPlanner, Verbose, TEXT("Ignoring ProcessExecutionRequest call due to HTNPlannerComponent still being paused"));
return;
}
//GEngine->AddOnScreenDebugMessage(-1, 1.5f, FColor::Yellow, TEXT("UHTNPlannerComponent::ProcessExecutionRequest()"));
if(PendingExecution.IsValid())
{
ProcessPendingExecution();
return;
}
if(NumStackElements == 0)
{
//BestPlan = nullptr;
if(CurrentPlannerAsset->bLoop)
{
// finished execution of plan and we want to loop, so re-start
RestartPlanner();
}
else
{
bIsRunning = false;
}
return;
}
#if HTN_LOG_RUNTIME_STATS
if(StartPlanningTime == FDateTime::MinValue())
{
StartPlanningTime = FDateTime::UtcNow();
}
#endif // HTN_LOG_RUNTIME_STATS
FDateTime PlanningStart = FDateTime::UtcNow();
while(NumStackElements > 0)
{
// our stack is not empty
FTimespan TimePlanned = FDateTime::UtcNow() - PlanningStart;
if(TimePlanned.GetTotalSeconds() >= CurrentPlannerAsset->MaxSearchTime)
{
// we've spent our maximum allowed search time for this tick on planning, so need to continue some other time
ScheduleExecutionUpdate();
#if HTN_LOG_RUNTIME_STATS
CumulativeSearchTimeMs += TimePlanned.GetTotalMilliseconds();
++CumulativeFrameCount;
#endif
return;
}
#if HTN_LOG_RUNTIME_STATS
++NumNodesExpanded;
#endif
if(PreviousPlan.IsValid())
{
UE_LOG(LogHTNPlanner, Warning, TEXT("%d nodes in data structure(s)"), NumStackElements);
}
if(bProbabilisticPlanReuse && bHitLeaf)
{
// we've hit a leaf node, so it's time to re-evaluate whether we're ignoring plan reuse probabilistically
bHitLeaf = false;
if(NumStackElements == PlanningStack.Num())
{
bIgnoringPlanReuse = false; // not ignoring plan reuse if everything's still in the non-prioritized stack
}
else
{
bIgnoringPlanReuse = (FMath::FRand() <= ProbabilityIgnorePlanReuse);
}
}
const FHTNStackElement StackTop = PopStackElement();
if(StackTop.Cost + Cast<UTaskNetwork>(StackTop.TaskNetwork->Task)->
GetHeuristicCost(StackTop.WorldState, StackTop.TaskNetwork->GetMemory()) >= BestCost)
{
if(!bDepthFirstSearch)
{
// everything remaining in the heap will be at least as bad, and maybe worse
PlanningStack.Empty();
NumStackElements = 0;
}
//.........这里部分代码省略.........
示例9: InitializeAfterSetActive
//.........这里部分代码省略.........
FileHandle->Write((const uint8*)&ServerPackageLicenseeVersion, sizeof(int32));
delete FileHandle;
}
}
// list of directories to skip
TArray<FString> DirectoriesToSkip;
TArray<FString> DirectoriesToNotRecurse;
// use the timestamp grabbing visitor to get all the content times
FLocalTimestampDirectoryVisitor Visitor(*InnerPlatformFile, DirectoriesToSkip, DirectoriesToNotRecurse, false);
TArray<FString> RootContentPaths;
FPackageName::QueryRootContentPaths( RootContentPaths );
for( TArray<FString>::TConstIterator RootPathIt( RootContentPaths ); RootPathIt; ++RootPathIt )
{
const FString& RootPath = *RootPathIt;
const FString& ContentFolder = FPackageName::LongPackageNameToFilename(RootPath);
InnerPlatformFile->IterateDirectory( *ContentFolder, Visitor);
}
// delete out of date files using the server cached files
for (TMap<FString, FDateTime>::TIterator It(ServerCachedFiles); It; ++It)
{
bool bDeleteFile = bDeleteAllFiles;
FString ServerFile = It.Key();
// Convert the filename to the client version
ConvertServerFilenameToClientFilename(ServerFile);
// Set it in the visitor file times list
Visitor.FileTimes.Add(ServerFile, FDateTime::MinValue());
if (bDeleteFile == false)
{
// Check the time stamps...
// get local time
FDateTime LocalTime = InnerPlatformFile->GetTimeStamp(*ServerFile);
// If local time == MinValue than the file does not exist in the cache.
if (LocalTime != FDateTime::MinValue())
{
FDateTime ServerTime = It.Value();
// delete if out of date
// We will use 1.0 second as the tolerance to cover any platform differences in resolution
FTimespan TimeDiff = LocalTime - ServerTime;
double TimeDiffInSeconds = TimeDiff.GetTotalSeconds();
bDeleteFile = (TimeDiffInSeconds > 1.0) || (TimeDiffInSeconds < -1.0);
if (bDeleteFile == true)
{
if (InnerPlatformFile->FileExists(*ServerFile) == true)
{
UE_LOG(LogNetworkPlatformFile, Display, TEXT("Deleting cached file: TimeDiff %5.3f, %s"), TimeDiffInSeconds, *It.Key());
}
else
{
// It's a directory
bDeleteFile = false;
}
}
}
}
if (bDeleteFile == true)
{
InnerPlatformFile->DeleteFile(*ServerFile);
}
}
// Any content files we have locally that were not cached, delete them
for (TMap<FString, FDateTime>::TIterator It(Visitor.FileTimes); It; ++It)
{
if (It.Value() != FDateTime::MinValue())
{
// This was *not* found in the server file list... delete it
UE_LOG(LogNetworkPlatformFile, Display, TEXT("Deleting cached file: %s"), *It.Key());
InnerPlatformFile->DeleteFile(*It.Key());
}
}
// make sure we can sync a file
FString TestSyncFile = FPaths::Combine(*(FPaths::EngineDir()), TEXT("Config/BaseEngine.ini"));
InnerPlatformFile->SetReadOnly(*TestSyncFile, false);
InnerPlatformFile->DeleteFile(*TestSyncFile);
if (InnerPlatformFile->FileExists(*TestSyncFile))
{
UE_LOG(LogNetworkPlatformFile, Fatal, TEXT("Could not delete file sync test file %s."), *TestSyncFile);
}
EnsureFileIsLocal(TestSyncFile);
if (!InnerPlatformFile->FileExists(*TestSyncFile) || InnerPlatformFile->FileSize(*TestSyncFile) < 1)
{
UE_LOG(LogNetworkPlatformFile, Fatal, TEXT("Could not sync test file %s."), *TestSyncFile);
}
}
}
FPlatformMisc::LowLevelOutputDebugStringf(TEXT("Network file startup time: %5.3f seconds\n"), NetworkFileStartupTime);
}
示例10: EditorPerfDump
/**
* Dumps the information held within the EditorPerfCaptureParameters struct into a CSV file.
* @param EditorPerfStats is the name of the struct that holds the needed performance information.
*/
void EditorPerfDump(EditorPerfCaptureParameters& EditorPerfStats)
{
UE_LOG(LogEditorAutomationTests, Log, TEXT("Begin generating the editor performance charts."));
//The file location where to save the data.
FString DataFileLocation = FPaths::Combine(*FPaths::AutomationLogDir(), TEXT("Performance"), *EditorPerfStats.MapName);
//Get the map load time (in seconds) from the text file that is created when the load map latent command is ran.
EditorPerfStats.MapLoadTime = 0;
FString MapLoadTimeFileLocation = FPaths::Combine(*DataFileLocation, TEXT("RAWMapLoadTime.txt"));
if (FPaths::FileExists(*MapLoadTimeFileLocation))
{
TArray<FString> SavedMapLoadTimes;
FAutomationEditorCommonUtils::CreateArrayFromFile(MapLoadTimeFileLocation, SavedMapLoadTimes);
EditorPerfStats.MapLoadTime = FCString::Atof(*SavedMapLoadTimes.Last());
}
//Filename for the RAW csv which holds the data gathered from a single test ran.
FString RAWCSVFilePath = FString::Printf(TEXT("%s/RAW_%s_%s.csv"), *DataFileLocation, *EditorPerfStats.MapName, *FDateTime::Now().ToString());
//Filename for the pretty csv file.
FString PerfCSVFilePath = FString::Printf(TEXT("%s/%s_Performance.csv"), *DataFileLocation, *EditorPerfStats.MapName);
//Create the raw csv and then add the title row it.
FArchive* RAWCSVArchive = IFileManager::Get().CreateFileWriter(*RAWCSVFilePath);
FString RAWCSVLine = (TEXT("Map Name, Changelist, Time Stamp, Map Load Time, Average FPS, Frame Time, Used Physical Memory, Used Virtual Memory, Used Peak Physical, Used Peak Virtual, Available Physical Memory, Available Virtual Memory\n"));
RAWCSVArchive->Serialize(TCHAR_TO_ANSI(*RAWCSVLine), RAWCSVLine.Len());
//Dump the stats from each run to the raw csv file and then close it.
for (int32 i = 0; i < EditorPerfStats.TimeStamp.Num(); i++)
{
//If the raw file isn't available to write to then we'll fail back this test.
if ( FAutomationEditorCommonUtils::IsArchiveWriteable(RAWCSVFilePath, RAWCSVArchive))
{
RAWCSVLine = FString::Printf(TEXT("%s,%s,%s,%.3f,%.1f,%.1f,%.0f,%.0f,%.0f,%.0f,%.0f,%.0f%s"), *EditorPerfStats.MapName, *FEngineVersion::Current().ToString(EVersionComponent::Changelist), *EditorPerfStats.FormattedTimeStamp[i], EditorPerfStats.MapLoadTime, EditorPerfStats.AverageFPS[i], EditorPerfStats.AverageFrameTime[i], EditorPerfStats.UsedPhysical[i], EditorPerfStats.UsedVirtual[i], EditorPerfStats.PeakUsedPhysical[i], EditorPerfStats.PeakUsedVirtual[i], EditorPerfStats.AvailablePhysical[i], EditorPerfStats.AvailableVirtual[i], LINE_TERMINATOR);
RAWCSVArchive->Serialize(TCHAR_TO_ANSI(*RAWCSVLine), RAWCSVLine.Len());
}
}
RAWCSVArchive->Close();
//Get the final pretty data for the Performance csv file.
float AverageFPS = FAutomationEditorCommonUtils::TotalFromFloatArray(EditorPerfStats.AverageFPS, true);
float AverageFrameTime = FAutomationEditorCommonUtils::TotalFromFloatArray(EditorPerfStats.AverageFrameTime, true);
float MemoryUsedPhysical = FAutomationEditorCommonUtils::TotalFromFloatArray(EditorPerfStats.UsedPhysical, true);
float MemoryAvailPhysAvg = FAutomationEditorCommonUtils::TotalFromFloatArray(EditorPerfStats.AvailablePhysical, true);
float MemoryAvailVirtualAvg = FAutomationEditorCommonUtils::TotalFromFloatArray(EditorPerfStats.AvailableVirtual, true);
float MemoryUsedVirtualAvg = FAutomationEditorCommonUtils::TotalFromFloatArray(EditorPerfStats.UsedVirtual, true);
float MemoryUsedPeak = FAutomationEditorCommonUtils::LargestValueInFloatArray(EditorPerfStats.PeakUsedPhysical);
float MemoryUsedPeakVirtual = FAutomationEditorCommonUtils::LargestValueInFloatArray(EditorPerfStats.PeakUsedVirtual);
//TestRunDuration is the length of time the test lasted in ticks.
FTimespan TestRunDuration = (EditorPerfStats.TimeStamp.Last().GetTicks() - EditorPerfStats.TimeStamp[0].GetTicks()) + ETimespan::TicksPerSecond;
//The performance csv file will be created if it didn't exist prior to the start of this test.
if (!FPaths::FileExists(*PerfCSVFilePath))
{
FArchive* FinalCSVArchive = IFileManager::Get().CreateFileWriter(*PerfCSVFilePath);
if ( FAutomationEditorCommonUtils::IsArchiveWriteable(PerfCSVFilePath, FinalCSVArchive))
{
FString FinalCSVLine = (TEXT("Date, Map Name, Changelist, Test Run Time , Map Load Time, Average FPS, Average MS, Used Physical KB, Used Virtual KB, Used Peak Physcial KB, Used Peak Virtual KB, Available Physical KB, Available Virtual KB\n"));
FinalCSVArchive->Serialize(TCHAR_TO_ANSI(*FinalCSVLine), FinalCSVLine.Len());
FinalCSVArchive->Close();
}
}
//Load the existing performance csv so that it doesn't get saved over and lost.
FString OldPerformanceCSVFile;
FFileHelper::LoadFileToString(OldPerformanceCSVFile, *PerfCSVFilePath);
FArchive* FinalCSVArchive = IFileManager::Get().CreateFileWriter(*PerfCSVFilePath);
if ( FAutomationEditorCommonUtils::IsArchiveWriteable(PerfCSVFilePath, FinalCSVArchive))
{
//Dump the old performance csv file data to the new csv file.
FinalCSVArchive->Serialize(TCHAR_TO_ANSI(*OldPerformanceCSVFile), OldPerformanceCSVFile.Len());
//Dump the pretty stats to the Performance CSV file and then close it so we can edit it while the engine is still running.
FString FinalCSVLine = FString::Printf(TEXT("%s,%s,%s,%.0f,%.3f,%.1f,%.1f,%.0f,%.0f,%.0f,%.0f,%.0f,%.0f%s"), *FDateTime::Now().ToString(), *EditorPerfStats.MapName, *FEngineVersion::Current().ToString(EVersionComponent::Changelist), TestRunDuration.GetTotalSeconds(), EditorPerfStats.MapLoadTime, AverageFPS, AverageFrameTime, MemoryUsedPhysical, MemoryUsedVirtualAvg, MemoryUsedPeak, MemoryUsedPeakVirtual, MemoryAvailPhysAvg, MemoryAvailVirtualAvg, LINE_TERMINATOR);
FinalCSVArchive->Serialize(TCHAR_TO_ANSI(*FinalCSVLine), FinalCSVLine.Len());
FinalCSVArchive->Close();
}
//Display the test results to the user.
UE_LOG(LogEditorAutomationTests, Display, TEXT("AVG FPS: '%.1f'"), AverageFPS);
UE_LOG(LogEditorAutomationTests, Display, TEXT("AVG Frame Time: '%.1f' ms"), AverageFrameTime);
UE_LOG(LogEditorAutomationTests, Display, TEXT("AVG Used Physical Memory: '%.0f' kb"), MemoryUsedPhysical);
UE_LOG(LogEditorAutomationTests, Display, TEXT("AVG Used Virtual Memory: '%.0f' kb"), MemoryUsedVirtualAvg);
UE_LOG(LogEditorAutomationTests, Display, TEXT("Performance csv file is located here: %s"), *FPaths::ConvertRelativePathToFull(PerfCSVFilePath));
UE_LOG(LogEditorAutomationTests, Log, TEXT("Performance csv file is located here: %s"), *FPaths::ConvertRelativePathToFull(PerfCSVFilePath));
UE_LOG(LogEditorAutomationTests, Log, TEXT("Raw performance csv file is located here: %s"), *FPaths::ConvertRelativePathToFull(RAWCSVFilePath));
}