You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
Allows fast iteration of C++ changes without restarting the application. To use, select the "Live Coding (Experimental)" mode from the drop down menu next to the editor's compile button, or type "LiveCoding" into the console for a monolithic build. Press Ctrl+Alt+F11 to find changes and compile.
Changes vs standalone Live++ version:
* UBT is used to execute builds. This allows standard UE4 adaptive unity mode, allows us to reuse object files when we do regular builds, supports using any build executor allowed by UBT (XGE, SNDBS, etc..).
* Adding new source files is supported.
* Custom visualizer for FNames is supported via a weakly linked symbol in a static library (Engine/Extras/NatvisHelpers).
* Settings are exposed in the editor's project settings dialog.
* Standalone application has been rewritten as a Slate app ("LiveCodingConsole"). There is an additional option to start the program as hidden, where it will not be visible until Ctrl+Alt+F11 is hit. Similarly, closing the window will hide it instead of closing the application.
* Does not require a standalone licensed version of Live++.
Known issues:
* Does not currently support class layout changes / object reinstancing
#rb none
#fyi Marc.Audy, Stefan.Boberg, Nick.Penwarden
#jira
[CL 5304722 by Ben Marsh in 4.22 branch]
169 lines
4.3 KiB
C++
169 lines
4.3 KiB
C++
// Copyright 2011-2019 Molecular Matters GmbH, all rights reserved.
|
|
|
|
#include "LC_Logging.h"
|
|
#include "Logging/LogMacros.h"
|
|
#include "LiveCodingLog.h"
|
|
#include <atomic>
|
|
|
|
namespace
|
|
{
|
|
// we want to be able to dump large things, including environment variable blocks, but 32k on the stack is too much
|
|
static const size_t PER_THREAD_BUFFER_SIZE = 32u * 1024u;
|
|
static thread_local char gtls_logBuffer[PER_THREAD_BUFFER_SIZE] = {};
|
|
|
|
// keeps track of the current indentation
|
|
static std::atomic<int> g_indentationLevel[logging::Channel::COUNT] = {};
|
|
|
|
// small lookup table for different levels of indentation
|
|
static const int MAX_INDENTATION_LEVELS = 7;
|
|
static const char* const INDENTATION_STRINGS[MAX_INDENTATION_LEVELS] =
|
|
{
|
|
"", // level 0
|
|
" o ", // level 1
|
|
" - ", // level 2
|
|
" * ", // level 3
|
|
" o ", // level 4
|
|
" - ", // level 5
|
|
" * " // level 6
|
|
};
|
|
|
|
// BEGIN EPIC MOD - Redirecting log output
|
|
static void DefaultOutputHandler(logging::Channel::Enum channel, logging::Type::Enum type, const wchar_t* const Message)
|
|
{
|
|
switch (type)
|
|
{
|
|
case logging::Type::LOG_WARNING:
|
|
UE_LOG(LogLiveCoding, Warning, TEXT("%s"), Message);
|
|
break;
|
|
case logging::Type::LOG_ERROR:
|
|
UE_LOG(LogLiveCoding, Error, TEXT("%s"), Message);
|
|
break;
|
|
default:
|
|
UE_LOG(LogLiveCoding, Display, TEXT("%s"), Message);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static logging::OutputHandlerType OutputHandler = &DefaultOutputHandler;
|
|
// END EPIC MOD - Redirecting log output
|
|
|
|
// BEGIN EPIC MOD - Explicit API for enabling log channels
|
|
static bool ChannelEnabled[logging::Channel::COUNT] = { };
|
|
// END EPIC MOD - Explicit API for enabling log channels
|
|
|
|
static bool IsChannelEnabled(logging::Channel::Enum channel, logging::Type::Enum type)
|
|
{
|
|
// warnings, errors and success logs should always be output to all channels
|
|
if (type != logging::Type::LOG_INFO)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
// BEGIN EPIC MOD - Explicit API for enabling log channels
|
|
switch (channel)
|
|
{
|
|
case logging::Channel::USER:
|
|
// user-visible logs are *always* logged
|
|
return true;
|
|
|
|
default:
|
|
// disabled or unknown channel
|
|
return ChannelEnabled[channel];
|
|
}
|
|
// END EPIC MOD - Explicit API for enabling log channels
|
|
}
|
|
}
|
|
|
|
|
|
logging::Indent::Indent(Channel::Enum channel)
|
|
: m_channel(channel)
|
|
{
|
|
IncrementIndentation(channel);
|
|
}
|
|
|
|
|
|
logging::Indent::~Indent(void)
|
|
{
|
|
DecrementIndentation(m_channel);
|
|
}
|
|
|
|
|
|
void logging::IncrementIndentation(Channel::Enum channel)
|
|
{
|
|
std::atomic_fetch_add(&g_indentationLevel[channel], 1);
|
|
}
|
|
|
|
|
|
void logging::DecrementIndentation(Channel::Enum channel)
|
|
{
|
|
std::atomic_fetch_sub(&g_indentationLevel[channel], 1);
|
|
}
|
|
|
|
|
|
const char* logging::GetIndentation(logging::Channel::Enum channel)
|
|
{
|
|
int indent = g_indentationLevel[channel];
|
|
if (indent >= MAX_INDENTATION_LEVELS)
|
|
{
|
|
return INDENTATION_STRINGS[MAX_INDENTATION_LEVELS - 1];
|
|
}
|
|
|
|
return INDENTATION_STRINGS[indent];
|
|
}
|
|
|
|
|
|
template <> void logging::LogNoFormat<logging::Channel::Enum::USER>(const wchar_t* const buffer)
|
|
{
|
|
// BEGIN EPIC MOD - Redirecting log output
|
|
OutputHandler(logging::Channel::Enum::USER, Type::LOG_INFO, buffer);
|
|
// END EPIC MOD - Redirecting log output
|
|
}
|
|
|
|
|
|
template <> void logging::LogNoFormat<logging::Channel::Enum::DEV>(const char* const buffer)
|
|
{
|
|
// BEGIN EPIC MOD - Redirecting log output
|
|
OutputHandler(logging::Channel::Enum::DEV, Type::LOG_INFO, ANSI_TO_TCHAR(buffer));
|
|
// END EPIC MOD - Redirecting log output
|
|
}
|
|
|
|
void logging::Log(Channel::Enum channel, Type::Enum type, const char* const format, ...)
|
|
{
|
|
if (!IsChannelEnabled(channel, type))
|
|
{
|
|
return;
|
|
}
|
|
|
|
va_list argptr;
|
|
va_start(argptr, format);
|
|
|
|
char (&buffer)[PER_THREAD_BUFFER_SIZE] = gtls_logBuffer;
|
|
_vsnprintf_s(buffer, _TRUNCATE, format, argptr);
|
|
|
|
// BEGIN EPIC MOD - Redirecting log output
|
|
OutputHandler(channel, type, ANSI_TO_TCHAR(buffer));
|
|
// END EPIC MOD - Redirecting log output
|
|
|
|
va_end(argptr);
|
|
}
|
|
|
|
// BEGIN EPIC MOD - Redirecting log output
|
|
void logging::EnableChannel(Channel::Enum channel, bool enabled)
|
|
{
|
|
check(channel != logging::Channel::USER || enabled);
|
|
ChannelEnabled[(int)channel] = enabled;
|
|
}
|
|
|
|
void logging::SetOutputHandler(logging::OutputHandlerType handler)
|
|
{
|
|
if (handler == nullptr)
|
|
{
|
|
OutputHandler = &DefaultOutputHandler;
|
|
}
|
|
else
|
|
{
|
|
OutputHandler = handler;
|
|
}
|
|
}
|
|
// END EPIC MOD - Redirecting log output
|