Add more contextual log printing on missing object/asset reference

#2414
This commit is contained in:
Wojtek Figat
2024-09-15 23:03:53 +02:00
parent 1fa0159079
commit a367d40913
6 changed files with 74 additions and 15 deletions

View File

@@ -1,9 +1,15 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#include "LogContext.h"
#include "Engine/Core/Log.h"
#include "Engine/Core/Types/Guid.h"
#include "Engine/Core/Types/String.h"
#include "Engine/Core/Types/StringBuilder.h"
#include "Engine/Core/Collections/Array.h"
#include "Engine/Scripting/Scripting.h"
#include "Engine/Scripting/Script.h"
#include "Engine/Content/Asset.h"
#include "Engine/Level/Actor.h"
#include "Engine/Threading/ThreadLocal.h"
struct LogContextThreadData
@@ -30,7 +36,7 @@ struct LogContextThreadData
Count--;
}
LogContextData Peek()
LogContextData Peek() const
{
return Count > 0 ? Ptr[Count - 1] : LogContextData();
}
@@ -38,12 +44,54 @@ struct LogContextThreadData
ThreadLocal<LogContextThreadData> GlobalLogContexts;
String LogContext::GetInfo()
void LogContext::Print(LogType verbosity)
{
LogContextData context = LogContext::Get();
if (context.ObjectID != Guid::Empty)
return String::Format(TEXT("(Loading source was {0})"), context.ObjectID);
return String::Empty;
auto& stack = GlobalLogContexts.Get();
if (stack.Count == 0)
return;
const StringView indentation(TEXT(" "));
StringBuilder msg;
for (int32 index = (int32)stack.Count - 1; index >= 0; index--)
{
// Build call hierarchy via indentation
msg.Clear();
for (uint32 i = index; i < stack.Count; i++)
msg.Append(indentation);
LogContextData& context = stack.Ptr[index];
if (context.ObjectID != Guid::Empty)
{
// Object reference context
msg.Append(TEXT(" Referenced by "));
if (ScriptingObject* object = Scripting::TryFindObject(context.ObjectID))
{
const StringAnsiView typeName(object->GetType().Fullname);
if (Asset* asset = ScriptingObject::Cast<Asset>(object))
{
msg.AppendFormat(TEXT("asset '{}' ({}, {})"), asset->GetPath(), asset->GetTypeName(), context.ObjectID);
}
else if (Actor* actor = ScriptingObject::Cast<Actor>(object))
{
msg.AppendFormat(TEXT("actor '{}' ({}, {})"), actor->GetNamePath(), String(typeName), context.ObjectID);
}
else if (Script* script = ScriptingObject::Cast<Script>(object))
{
msg.AppendFormat(TEXT("script '{}' ({}, {})"), script->GetNamePath(), String(typeName), context.ObjectID);
}
else
{
msg.AppendFormat(TEXT("object {} ({})"), String(typeName), context.ObjectID);
}
}
else
{
msg.AppendFormat(TEXT("object {}"), context.ObjectID);
}
}
// Print message
Log::Logger::Write(verbosity, msg.ToStringView());
}
}
void LogContext::Push(const Guid& id)