Massive refactoring in FormatMessage and LuaCallNode
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
|
||||
#include "FormatDataLibrary.h"
|
||||
#include "Editor.h"
|
||||
#include "EdGraphSchema_K2.h"
|
||||
#include "Internationalization/TextFormatter.h"
|
||||
#include "Layout/Geometry.h"
|
||||
#include "Widgets/Layout/Anchors.h"
|
||||
#include "Common.h"
|
||||
@@ -49,6 +52,54 @@ void UlxFormatDataLibrary::ScanForConverters()
|
||||
}
|
||||
}
|
||||
|
||||
UFunction* UlxFormatDataLibrary::GetConverterForPinType(const UEdGraphSchema_K2 *Schema, const FEdGraphPinType& PinType, bool AllowWild)
|
||||
{
|
||||
// Special case: wildcard pins are unconnected pins.
|
||||
if ((PinType.PinCategory == UEdGraphSchema_K2::PC_Wildcard) && AllowWild)
|
||||
{
|
||||
return UlxFormatDataLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxFormatDataLibrary, FormatArgumentDataBlank));
|
||||
}
|
||||
|
||||
// Scan the cached converter list for a matching type.
|
||||
UlxFormatDataLibrary* FormatDataLib = GEditor->GetEditorSubsystem<UlxFormatDataLibrary>();
|
||||
for (UFunction* Function : FormatDataLib->Converters)
|
||||
{
|
||||
FProperty* ValueProperty = Function->FindPropertyByName(TEXT("AutoConvertedValue"));
|
||||
FEdGraphPinType ValuePinType;
|
||||
if (!Schema->ConvertPropertyToPinType(ValueProperty, ValuePinType)) continue;
|
||||
if (!Schema->ArePinTypesEquivalent(PinType, ValuePinType)) continue;
|
||||
return Function;
|
||||
}
|
||||
|
||||
// A general handler for Enums.
|
||||
if ((PinType.PinCategory == UEdGraphSchema_K2::PC_Byte) && (nullptr != Cast<const UEnum>(PinType.PinSubCategoryObject)))
|
||||
{
|
||||
return UlxFormatDataLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxFormatDataLibrary, FormatArgumentDataEnum));
|
||||
}
|
||||
|
||||
// A case for subclasses of 'Object' which are not exactly 'Object'.
|
||||
if (PinType.PinCategory == UEdGraphSchema_K2::PC_Object)
|
||||
{
|
||||
return UlxFormatDataLibrary::StaticClass()->FindFunctionByName(GET_MEMBER_NAME_CHECKED(UlxFormatDataLibrary, FormatArgumentDataObject));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ELogVerbosity::Type UlxFormatDataLibrary::ConvertElxFormatLogVerbosity(ElxFormatLogVerbosity Verbosity) {
|
||||
switch (Verbosity) {
|
||||
case ElxFormatLogVerbosity::Error: return ELogVerbosity::Error;
|
||||
case ElxFormatLogVerbosity::Warning: return ELogVerbosity::Warning;
|
||||
case ElxFormatLogVerbosity::Display: return ELogVerbosity::Display;
|
||||
case ElxFormatLogVerbosity::Log: return ELogVerbosity::Log;
|
||||
case ElxFormatLogVerbosity::ThrottledDisplay: return ELogVerbosity::Display;
|
||||
case ElxFormatLogVerbosity::ThrottledLog: return ELogVerbosity::Log;
|
||||
case ElxFormatLogVerbosity::Verbose: return ELogVerbosity::Verbose;
|
||||
case ElxFormatLogVerbosity::VeryVerbose: return ELogVerbosity::VeryVerbose;
|
||||
case ElxFormatLogVerbosity::Fatal: return ELogVerbosity::Fatal;
|
||||
}
|
||||
}
|
||||
|
||||
FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataBool(bool AutoConvertedValue, const FString &Name)
|
||||
{
|
||||
FFormatArgumentData Result;
|
||||
@@ -248,3 +299,55 @@ FFormatArgumentData UlxFormatDataLibrary::FormatArgumentDataEnum(uint8 Value, co
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
void UlxFormatDataLibrary::FormatLogMessageInternal(UObject *Context, ElxFormatLogVerbosity Verbosity, const FString &InPattern, TArray<FFormatArgumentData> InArgs)
|
||||
{
|
||||
// For throttled verbosity levels, suppress repeated messages with the
|
||||
// same format pattern. We key on the blueprint name + format pattern,
|
||||
// and allow at most one message per second per key.
|
||||
//
|
||||
if ((Verbosity == ElxFormatLogVerbosity::ThrottledDisplay) || (Verbosity == ElxFormatLogVerbosity::ThrottledLog))
|
||||
{
|
||||
static TMap<FString, double> LastLogTime;
|
||||
double Now = FPlatformTime::Seconds();
|
||||
FString Key = Context->GetClass()->GetName() + TEXT("::") + InPattern;
|
||||
double &Last = LastLogTime.FindOrAdd(Key, 0.0);
|
||||
if (Now - Last < 1.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
Last = Now;
|
||||
}
|
||||
|
||||
// Generate the formatted string.
|
||||
//
|
||||
FText InPatternText(FText::FromString(InPattern));
|
||||
FText Message = FTextFormatter::Format(MoveTemp(InPatternText), MoveTemp(InArgs), false, false);
|
||||
FString MessageString = Message.ToString();
|
||||
|
||||
// Get the blueprint name.
|
||||
//
|
||||
// Normally, the log function expects you to pass in a filename, and a log
|
||||
// category name. We use the blueprint name for both.
|
||||
//
|
||||
// Using the blueprint name as a log category name is not technically
|
||||
// correct. However, there is no correct way to create log categories
|
||||
// from inside of blueprints. Doing it this way at least produces a reasonable
|
||||
// message inside the log. What doesn't work correctly is the log message
|
||||
// suppression system. Ie, console commands like 'log <category> verbose'
|
||||
// don't have any effect here. The design of the log message suppression
|
||||
// system is such that there just is no reasonable way to hook into it from
|
||||
// inside of blueprints.
|
||||
//
|
||||
FString BlueprintNameString = Context->GetClass()->GetName();
|
||||
auto BlueprintNameAnsi = StringCast<ANSICHAR>(*BlueprintNameString);
|
||||
FLogCategoryName BlueprintNameLogCategory(Context->GetClass()->GetFName());
|
||||
|
||||
// Output to Log
|
||||
//
|
||||
ELogVerbosity::Type VerbosityValue = ConvertElxFormatLogVerbosity(Verbosity);
|
||||
if (VerbosityValue <= ELogVerbosity::COMPILED_IN_MINIMUM_VERBOSITY)
|
||||
{
|
||||
FMsg::Logf(BlueprintNameAnsi.Get(), 0, BlueprintNameLogCategory, VerbosityValue, TEXT("%s"), *MessageString);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user