Files
UnrealEngine/Engine/Source/Runtime/Solaris/uLangUE/Private/ULangUE.cpp
2025-05-18 13:04:45 +08:00

112 lines
3.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "ULangUE.h"
#include <cstdio>
#include "CoreGlobals.h"
#include "Misc/OutputDeviceRedirector.h"
#include "SolarisLogging.h"
#include "uLang/Common/Common.h"
#include "uLang/Common/Text/UTF8String.h"
DEFINE_LOG_CATEGORY(LogSolaris);
/* uLangUE_Impl
*****************************************************************************/
namespace uLangUE_Impl
{
size_t NumActiveInitializations{0};
/// Function that is called by uLang when an assert fails
uLang::EErrorAction AssertFailed(uLang::EAssertSeverity Severity, const ANSICHAR* ExprText, const ANSICHAR* FileText, int32_t Line, const ANSICHAR* Format, ...)
{
va_list Args;
va_start(Args, Format);
uLang::CUTF8String Message(Format, Args);
va_end(Args);
#if DO_CHECK || DO_GUARD_SLOW || DO_ENSURE
FDebug::EnsureFailed(ExprText, FileText, Line, nullptr, UTF8_TO_TCHAR(*Message));
#else
// Use Error instead of Fatal so we don't terminate the process. This unfortunately won't
// report the failure to CR, but at least for Severity=Fatal, the caller will terminate the
// process, and this will have printed the message to the log.
UE_LOG(LogSolaris, Error, TEXT("%s"), UTF8_TO_TCHAR(*Message));
#endif
return (Severity == uLang::EAssertSeverity::Fatal || FPlatformMisc::IsDebuggerPresent())
? uLang::EErrorAction::Break
: uLang::EErrorAction::Continue;
}
constexpr uLang::SSystemParams::FAssert AssertFailedFn = &AssertFailed;
void LogMessage(uLang::ELogVerbosity Verbosity, const char* Format, ...)
{
#if !NO_LOGGING
va_list Args;
va_start(Args, Format);
uLang::CUTF8String Message(Format, Args);
va_end(Args);
// Only print if the level is less than the global verbosity
if (uLang::GetSystemParams()._Verbosity < Verbosity)
{
return;
}
ELogVerbosity::Type UEVerbosity;
switch (Verbosity)
{
case uLang::ELogVerbosity::Error: UEVerbosity = ELogVerbosity::Error; break;
case uLang::ELogVerbosity::Warning: UEVerbosity = ELogVerbosity::Warning; break;
case uLang::ELogVerbosity::Log: UEVerbosity = ELogVerbosity::Log; break;
case uLang::ELogVerbosity::Verbose: UEVerbosity = ELogVerbosity::Verbose; break;
case uLang::ELogVerbosity::Display:
default: UEVerbosity = ELogVerbosity::Display; break;
}
// Print to console
if (Verbosity <= uLang::ELogVerbosity::Verbose)
{
FILE* Out = Verbosity <= uLang::ELogVerbosity::Warning ? stderr : stdout;
::fprintf(Out, "%s\n", *Message);
}
// Also send to log
FString MessageW(*Message);
GLog->Serialize(*MessageW, UEVerbosity, LogSolaris.GetCategoryName());
#endif
}
}
void uLangUE::Initialize()
{
// Only initialize uLang if it was previously uninitialized or deinitialized.
const size_t PreviousNumActiveInitializations = uLangUE_Impl::NumActiveInitializations++;
if (!PreviousNumActiveInitializations)
{
// Initialize uLang core
uLang::SSystemParams SystemParams = {
ULANG_API_VERSION,
[](size_t NumBytes) -> void* { return FMemory::Malloc(NumBytes); },
[](void* Memory, size_t NumBytes) -> void* { return FMemory::Realloc(Memory, NumBytes); },
&FMemory::Free,
uLangUE_Impl::AssertFailedFn,
&uLangUE_Impl::LogMessage,
};
uLang::Initialize(SystemParams);
}
}
void uLangUE::DeInitialize()
{
// Only deinitialize uLang if this was the last active initialization.
const size_t PreviousNumActiveInitializations = uLangUE_Impl::NumActiveInitializations--;
ULANG_ASSERT(PreviousNumActiveInitializations > 0);
if (PreviousNumActiveInitializations == 1)
{
uLang::DeInitialize();
}
}