OLS/Plugins/Developer/RiderLink/Source/RiderLogging/Private/RiderLogging.cpp
2024-09-22 17:11:19 -04:00

142 lines
4.1 KiB
C++

#include "RiderLogging.hpp"
#include "BlueprintProvider.hpp"
#include "IRiderLink.hpp"
#include "Model/Library/UE4Library/LogMessageInfo.Pregenerated.h"
#include "Model/Library/UE4Library/StringRange.Pregenerated.h"
#include "Model/Library/UE4Library/UnrealLogEvent.Pregenerated.h"
#include "Internationalization/Regex.h"
#include "Misc/DateTime.h"
#include "Modules/ModuleManager.h"
#define LOCTEXT_NAMESPACE "RiderLogging"
DEFINE_LOG_CATEGORY(FLogRiderLoggingModule);
IMPLEMENT_MODULE(FRiderLoggingModule, RiderLogging);
namespace LoggingExtensionImpl
{
static TArray<rd::Wrapper<JetBrains::EditorPlugin::StringRange>> GetPathRanges(
const FRegexPattern& Pattern,
const FString& Str)
{
using JetBrains::EditorPlugin::StringRange;
FRegexMatcher Matcher(Pattern, Str);
TArray<rd::Wrapper<StringRange>> Ranges;
while (Matcher.FindNext())
{
const int Start = Matcher.GetMatchBeginning();
const int End = Matcher.GetMatchEnding();
FString PathName = Str.Mid(Start, End - Start);
if (BluePrintProvider::IsBlueprint(PathName))
Ranges.Emplace(StringRange(Start, End));
}
return Ranges;
}
static TArray<rd::Wrapper<JetBrains::EditorPlugin::StringRange>> GetMethodRanges(
const FRegexPattern& Pattern,
const FString& Str)
{
using JetBrains::EditorPlugin::StringRange;
FRegexMatcher Matcher(Pattern, Str);
TArray<rd::Wrapper<StringRange>> Ranges;
while (Matcher.FindNext())
{
Ranges.Emplace(StringRange(Matcher.GetMatchBeginning(), Matcher.GetMatchEnding()));
}
return Ranges;
}
static bool SendMessageToRider(const JetBrains::EditorPlugin::LogMessageInfo& MessageInfo, const FString& Message)
{
static const FRegexPattern PathPattern = FRegexPattern(TEXT("(/[\\w\\.]+)+"));
static const FRegexPattern MethodPattern = FRegexPattern(TEXT("[0-9a-z_A-Z]+::~?[0-9a-z_A-Z]+"));
return IRiderLinkModule::Get().FireAsyncAction(
[&MessageInfo, &Message] (JetBrains::EditorPlugin::RdEditorModel const& RdEditorModel)
{
rd::ISignal<JetBrains::EditorPlugin::UnrealLogEvent> const& UnrealLog = RdEditorModel.get_unrealLog();
UnrealLog.fire({
MessageInfo,
Message,
GetPathRanges(PathPattern, Message),
GetMethodRanges(MethodPattern, Message)
});
});
}
void SendMessageInChunks(FString* Msg, const JetBrains::EditorPlugin::LogMessageInfo& MessageInfo)
{
static int NUMBER_OF_CHUNKS = 1024;
while (!Msg->IsEmpty())
{
SendMessageToRider(MessageInfo, Msg->Left(NUMBER_OF_CHUNKS));
*Msg = Msg->RightChop(NUMBER_OF_CHUNKS);
}
}
void ScheduledSendMessage(FString* Msg, const JetBrains::EditorPlugin::LogMessageInfo& MessageInfo)
{
FString ToSend;
while (Msg->Split("\n", &ToSend, Msg))
{
SendMessageInChunks(&ToSend, MessageInfo);
}
SendMessageInChunks(Msg, MessageInfo);
}
}
void FRiderLoggingModule::StartupModule()
{
UE_LOG(FLogRiderLoggingModule, Verbose, TEXT("STARTUP START"));
static const auto START_TIME = FDateTime::UtcNow().ToUnixTimestamp();
static const auto GetTimeNow = [](double Time) -> rd::DateTime
{
return rd::DateTime(START_TIME + static_cast<int64>(Time));
};
ModuleLifetimeDef = IRiderLinkModule::Get().CreateNestedLifetimeDefinition();
LoggingScheduler = MakeUnique<rd::SingleThreadScheduler>(ModuleLifetimeDef.lifetime, "LoggingScheduler");
ModuleLifetimeDef.lifetime->bracket(
[this]()
{
OutputDevice.Setup([this](const TCHAR* msg, ELogVerbosity::Type Type, const FName& Name, TOptional<double> Time)
{
if (Type > ELogVerbosity::All) return;
rd::optional<rd::DateTime> DateTime;
if (Time)
{
DateTime = GetTimeNow(Time.GetValue());
}
const FString PlainName = Name.GetPlainNameString();
const JetBrains::EditorPlugin::LogMessageInfo MessageInfo{Type, PlainName, DateTime};
LoggingScheduler->queue([Msg = FString(msg), MessageInfo]() mutable
{
LoggingExtensionImpl::ScheduledSendMessage(&Msg, MessageInfo);
});
});
},
[this]()
{
OutputDevice.TearDown();
});
UE_LOG(FLogRiderLoggingModule, Verbose, TEXT("STARTUP FINISH"));
}
void FRiderLoggingModule::ShutdownModule()
{
UE_LOG(FLogRiderLoggingModule, Verbose, TEXT("SHUTDOWN START"));
ModuleLifetimeDef.terminate();
UE_LOG(FLogRiderLoggingModule, Verbose, TEXT("SHUTDOWN FINISH"));
}
#undef LOCTEXT_NAMESPACE