Files
UnrealEngine/Engine/Source/Programs/Unsync/Private/UnsyncLog.h
2025-05-18 13:04:45 +08:00

175 lines
6.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "UnsyncCommon.h"
namespace unsync {
extern thread_local bool GLogVerbose;
extern bool GLogVeryVerbose;
extern bool GLogSilent;
extern bool GBreakOnError;
extern bool GBreakOnWarning;
extern thread_local uint32 GLogIndent;
extern bool GLogProgress; // Whether to output @progress and @status markers to stdout
extern bool GLogMachineReadable; // Whether output is intended for other programs rather than humans
struct FError;
struct FLogIndentScope
{
uint32 Next = 0;
uint32 Prev = 0;
FLogIndentScope(uint32 InN = 2, bool bInOverride = false) : Next(InN), Prev(GLogIndent)
{
if (bInOverride)
{
GLogIndent = InN;
}
else
{
GLogIndent += Next;
}
}
~FLogIndentScope() { GLogIndent = Prev; }
FLogIndentScope(const FLogIndentScope&) = delete;
FLogIndentScope& operator=(const FLogIndentScope&) = delete;
};
struct FLogVerbosityScope
{
bool bNext = false;
bool bPrev = false;
FLogVerbosityScope(bool InNext) : bNext(InNext), bPrev(GLogVerbose) { GLogVerbose = bNext; }
~FLogVerbosityScope() { GLogVerbose = bPrev; }
FLogVerbosityScope(const FLogVerbosityScope&) = delete;
FLogVerbosityScope& operator=(const FLogVerbosityScope&) = delete;
};
struct FLogFileScope
{
FLogFileScope(const wchar_t* Filename);
~FLogFileScope();
};
struct FLogFlushScope
{
~FLogFlushScope();
};
enum class ELogLevel
{
Error = 0,
Warning = 1,
Info = 2,
Debug = 3,
Trace = 4,
// Special log level to signify output that's intended to be machine-readable.
// This is always written to stdout, while other modes may be written to stderr in some cases.
MachineReadable = 5,
};
void LogFlush();
void LogPrintf(ELogLevel Level, const wchar_t* Str, ...);
void LogError(const FError& E, std::wstring ExtraContext = {});
void LogProgress(const wchar_t* ItemName, uint64 Current, uint64 Total);
void LogStatus(const wchar_t* ItemName, const wchar_t* Status);
inline void
LogGlobalProgress(uint64 Current, uint64 Total)
{
LogProgress(nullptr, Current, Total);
}
inline void
LogGlobalStatus(const wchar_t* Status)
{
LogStatus(nullptr, Status);
}
void SetCrashDumpPath(const FPath& Path);
bool GetCrashDumpPath(FPath& OutPath);
bool LogWriteCrashDump(void* ExceptionPointers);
void LogSaveCommandLineUtf8(int Argc, char** Argv);
#define UNSYNC_LOG_INDENT FLogIndentScope UNSYNC_CONCAT(log_indent_, __LINE__);
#define UNSYNC_LOG_INDENT_N(N) FLogIndentScope UNSYNC_CONCAT(log_indent_, __LINE__)(N);
#define UNSYNC_LOG(text, ...) \
{ \
LogPrintf(ELogLevel::Info, text L"\n", ##__VA_ARGS__); \
}
#define UNSYNC_WARNING(text, ...) \
{ \
LogPrintf(ELogLevel::Warning, text L"\n", ##__VA_ARGS__); \
if (GBreakOnWarning) \
UNSYNC_BREAK(); \
}
#define UNSYNC_ERROR(text, ...) \
{ \
LogPrintf(ELogLevel::Error, text L"\n", ##__VA_ARGS__); \
if (GBreakOnError) \
UNSYNC_BREAK(); \
}
#define UNSYNC_FATAL(text, ...) \
{ \
LogPrintf(ELogLevel::Error, text L"\n", ##__VA_ARGS__); \
UNSYNC_BREAK(); \
}
#define UNSYNC_VERBOSE(text, ...) \
{ \
LogPrintf(ELogLevel::Debug, text L"\n", ##__VA_ARGS__); \
}
#define UNSYNC_VERBOSE2(text, ...) \
{ \
LogPrintf(ELogLevel::Trace, text L"\n", ##__VA_ARGS__); \
}
#define UNSYNC_ASSERT(cond) \
{ \
if (!(cond)) \
{ \
LogPrintf(ELogLevel::Error, L"Assertion failed: " UNSYNC_WSTR(cond) L"\n"); \
UNSYNC_BREAK(); \
} \
}
#define UNSYNC_ASSERTF(cond, text, ...) \
{ \
if (!(cond)) \
{ \
LogPrintf(ELogLevel::Error, L"Assertion failed: " UNSYNC_WSTR(cond) L". " text L"\n", ##__VA_ARGS__); \
UNSYNC_BREAK(); \
} \
}
#define UNSYNC_BREAK_ON_ERROR \
{ \
if (GBreakOnError) \
UNSYNC_BREAK(); \
}
#define UNSYNC_BREAK_ON_WARNING \
{ \
if (GBreakOnWarning) \
UNSYNC_BREAK(); \
}
#define UNSYNC_BREAK_ON_ERROR_LEVEL(LogLevel) \
{ \
if (LogLevel == ELogLevel::Error && GBreakOnError) \
UNSYNC_BREAK(); \
}
#define UNSYNC_BREAK_ON_WARNING_LEVEL(LogLevel) \
{ \
if (LogLevel == ELogLevel::Warning && GBreakOnWarning) \
UNSYNC_BREAK(); \
}
} // namespace unsync