Merge branch 'Menotdan-load-source-log'
This commit is contained in:
@@ -228,7 +228,7 @@ namespace FlaxEditor.Modules
|
||||
new SearchResult { Name = item.ShortName, Type = assetItem.TypeName, Item = item }
|
||||
};
|
||||
}
|
||||
var actor = FlaxEngine.Object.Find<Actor>(ref id);
|
||||
var actor = FlaxEngine.Object.Find<Actor>(ref id, true);
|
||||
if (actor != null)
|
||||
{
|
||||
return new List<SearchResult>
|
||||
@@ -236,6 +236,16 @@ namespace FlaxEditor.Modules
|
||||
new SearchResult { Name = actor.Name, Type = actor.TypeName, Item = actor }
|
||||
};
|
||||
}
|
||||
var script = FlaxEngine.Object.Find<Script>(ref id, true);
|
||||
if (script != null && script.Actor != null)
|
||||
{
|
||||
string actorPathStart = $"{script.Actor.Name}/";
|
||||
|
||||
return new List<SearchResult>
|
||||
{
|
||||
new SearchResult { Name = $"{actorPathStart}{script.TypeName}", Type = script.TypeName, Item = script }
|
||||
};
|
||||
}
|
||||
}
|
||||
Profiler.BeginEvent("ContentFinding.Search");
|
||||
|
||||
@@ -388,6 +398,13 @@ namespace FlaxEditor.Modules
|
||||
Editor.Instance.SceneEditing.Select(actor);
|
||||
Editor.Instance.Windows.EditWin.Viewport.FocusSelection();
|
||||
break;
|
||||
case Script script:
|
||||
if (script.Actor != null)
|
||||
{
|
||||
Editor.Instance.SceneEditing.Select(script.Actor);
|
||||
Editor.Instance.Windows.EditWin.Viewport.FocusSelection();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
67
Source/Engine/Core/LogContext.cpp
Normal file
67
Source/Engine/Core/LogContext.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "LogContext.h"
|
||||
#include "Engine/Core/Types/Guid.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Threading/ThreadLocal.h"
|
||||
|
||||
struct LogContextThreadData
|
||||
{
|
||||
LogContextData* Ptr;
|
||||
uint32 Count;
|
||||
uint32 Capacity;
|
||||
|
||||
void Push(LogContextData&& item)
|
||||
{
|
||||
if (Count == Capacity)
|
||||
{
|
||||
Capacity = Capacity == 0 ? 32 : Capacity * 2;
|
||||
auto ptr = (LogContextData*)Allocator::Allocate(Capacity * sizeof(LogContextData));
|
||||
Platform::MemoryCopy(ptr, Ptr, Count * sizeof(LogContextData));
|
||||
Allocator::Free(Ptr);
|
||||
Ptr = ptr;
|
||||
}
|
||||
Ptr[Count++] = MoveTemp(item);
|
||||
}
|
||||
|
||||
void Pop()
|
||||
{
|
||||
Count--;
|
||||
}
|
||||
|
||||
LogContextData Peek()
|
||||
{
|
||||
return Count == 0 ? Ptr[Count] : LogContextData();
|
||||
}
|
||||
};
|
||||
|
||||
ThreadLocal<LogContextThreadData> GlobalLogContexts;
|
||||
|
||||
String LogContext::GetInfo()
|
||||
{
|
||||
LogContextData context = LogContext::Get();
|
||||
if (context.ObjectID != Guid::Empty)
|
||||
return String::Format(TEXT("(Loading source was {0})"), context.ObjectID);
|
||||
return String::Empty;
|
||||
}
|
||||
|
||||
void LogContext::Push(const Guid& id)
|
||||
{
|
||||
LogContextData context;
|
||||
context.ObjectID = id;
|
||||
auto& stack = GlobalLogContexts.Get();
|
||||
stack.Push(MoveTemp(context));
|
||||
}
|
||||
|
||||
void LogContext::Pop()
|
||||
{
|
||||
auto& stack = GlobalLogContexts.Get();
|
||||
stack.Pop();
|
||||
}
|
||||
|
||||
LogContextData LogContext::Get()
|
||||
{
|
||||
auto& stack = GlobalLogContexts.Get();
|
||||
return stack.Peek();
|
||||
}
|
||||
77
Source/Engine/Core/LogContext.h
Normal file
77
Source/Engine/Core/LogContext.h
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Config.h"
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
|
||||
class String;
|
||||
struct Guid;
|
||||
|
||||
/// <summary>
|
||||
/// Log context data structure. Contains different kinds of context data for different situtations.
|
||||
/// </summary>
|
||||
API_STRUCT(NoDefault) struct FLAXENGINE_API LogContextData
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_STRUCTURE(LogContextData)
|
||||
|
||||
/// <summary>
|
||||
/// A GUID for an object which this context applies to.
|
||||
/// </summary>
|
||||
API_FIELD() Guid ObjectID;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct TIsPODType<LogContextData>
|
||||
{
|
||||
enum { Value = true };
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Log context interaction class. Methods are thread local, and as such, the context is as well.
|
||||
/// This system is used to pass down important information to be logged through large callstacks
|
||||
/// which don't have any reason to be passing down the information otherwise.
|
||||
/// </summary>
|
||||
API_CLASS(Static) class FLAXENGINE_API LogContext
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(LogContext)
|
||||
|
||||
/// <summary>
|
||||
/// Adds a log context element to the stack to be displayed in warning and error logs.
|
||||
/// </summary>
|
||||
/// <param name="id">The ID of the object this context applies to.</param>
|
||||
API_FUNCTION() static void Push(const Guid& id);
|
||||
|
||||
/// <summary>
|
||||
/// Pops a log context element off of the stack and discards it.
|
||||
/// </summary>
|
||||
API_FUNCTION() static void Pop();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the log context element off the top of stack.
|
||||
/// </summary>
|
||||
/// <returns>The log context element at the top of the stack.</returns>
|
||||
API_FUNCTION() static LogContextData Get();
|
||||
|
||||
/// <summary>
|
||||
/// Returns a string which represents the current log context on the stack.
|
||||
/// </summary>
|
||||
/// <returns>The formatted string representing the current log context.</returns>
|
||||
API_FUNCTION() static String GetInfo();
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Helper structure used to call LogContext Push/Pop within single code block.
|
||||
/// </summary>
|
||||
struct LogContextScope
|
||||
{
|
||||
FORCE_INLINE LogContextScope(const Guid& id)
|
||||
{
|
||||
LogContext::Push(id);
|
||||
}
|
||||
|
||||
FORCE_INLINE ~LogContextScope()
|
||||
{
|
||||
LogContext::Pop();
|
||||
}
|
||||
};
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Core/Cache.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/LogContext.h"
|
||||
#include "Engine/Scripting/Scripting.h"
|
||||
#include "Engine/Serialization/JsonTools.h"
|
||||
#include "Engine/Serialization/ISerializeModifier.h"
|
||||
@@ -247,6 +248,7 @@ void SceneObjectsFactory::Deserialize(Context& context, SceneObject* obj, ISeria
|
||||
CHECK(obj);
|
||||
#endif
|
||||
ISerializeModifier* modifier = context.GetModifier();
|
||||
LogContextScope logContext(obj->GetID());
|
||||
|
||||
// Check for prefab instance
|
||||
Guid prefabObjectId;
|
||||
|
||||
@@ -126,10 +126,11 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
/// <param name="id">Unique ID of the object.</param>
|
||||
/// <typeparam name="T">Type of the object.</typeparam>
|
||||
/// <param name="skipLog">Whether or not to log warnings when objects aren't found.</param>
|
||||
/// <returns>Found object or null if missing.</returns>
|
||||
public static T Find<T>(ref Guid id) where T : Object
|
||||
public static T Find<T>(ref Guid id, bool skipLog = false) where T : Object
|
||||
{
|
||||
return Internal_FindObject(ref id, typeof(T)) as T;
|
||||
return Internal_FindObject(ref id, typeof(T), skipLog) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -137,10 +138,11 @@ namespace FlaxEngine
|
||||
/// </summary>
|
||||
/// <param name="id">Unique ID of the object.</param>
|
||||
/// <param name="type">Type of the object.</param>
|
||||
/// <param name="skipLog">Whether or not to log warnings when objects aren't found.</param>
|
||||
/// <returns>Found object or null if missing.</returns>
|
||||
public static Object Find(ref Guid id, Type type)
|
||||
public static Object Find(ref Guid id, Type type, bool skipLog = false)
|
||||
{
|
||||
return Internal_FindObject(ref id, type);
|
||||
return Internal_FindObject(ref id, type, skipLog);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -335,7 +337,7 @@ namespace FlaxEngine
|
||||
internal static partial string Internal_GetTypeName(IntPtr obj);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial Object Internal_FindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
internal static partial Object Internal_FindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type, [MarshalAs(UnmanagedType.U1)] bool skipLog = false);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial Object Internal_TryFindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "ManagedCLR/MCore.h"
|
||||
#include "ManagedCLR/MException.h"
|
||||
#include "Internal/StdTypesContainer.h"
|
||||
#include "Engine/Core/LogContext.h"
|
||||
#include "Engine/Core/ObjectsRemovalService.h"
|
||||
#include "Engine/Core/Types/TimeSpan.h"
|
||||
#include "Engine/Core/Types/Stopwatch.h"
|
||||
@@ -880,7 +881,7 @@ ScriptingObject* Scripting::FindObject(Guid id, const MClass* type)
|
||||
// Check type
|
||||
if (!type || result->Is(type))
|
||||
return result;
|
||||
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}.", id, String(result->GetType().Fullname), String(type->GetFullName()));
|
||||
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}. {3}", id, String(result->GetType().Fullname), String(type->GetFullName()), LogContext::GetInfo());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -899,7 +900,7 @@ ScriptingObject* Scripting::FindObject(Guid id, const MClass* type)
|
||||
return asset;
|
||||
}
|
||||
|
||||
LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}.", id, String(type->GetFullName()));
|
||||
LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}. {2}", id, String(type->GetFullName()), LogContext::GetInfo());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "BinaryModule.h"
|
||||
#include "Engine/Level/Actor.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/LogContext.h"
|
||||
#include "Engine/Core/Types/Pair.h"
|
||||
#include "Engine/Utilities/StringConverter.h"
|
||||
#include "Engine/Content/Asset.h"
|
||||
@@ -708,7 +709,7 @@ DEFINE_INTERNAL_CALL(MString*) ObjectInternal_GetTypeName(ScriptingObject* obj)
|
||||
return MUtils::ToString(obj->GetType().Fullname);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject* type)
|
||||
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject* type, bool skipLog = false)
|
||||
{
|
||||
if (!id->IsValid())
|
||||
return nullptr;
|
||||
@@ -725,15 +726,20 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject*
|
||||
{
|
||||
if (klass && !obj->Is(klass))
|
||||
{
|
||||
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}.", *id, String(obj->GetType().Fullname), String(klass->GetFullName()));
|
||||
if (!skipLog)
|
||||
LOG(Warning, "Found scripting object with ID={0} of type {1} that doesn't match type {2}. {3}", *id, String(obj->GetType().Fullname), String(klass->GetFullName()), LogContext::GetInfo());
|
||||
return nullptr;
|
||||
}
|
||||
return obj->GetOrCreateManagedInstance();
|
||||
}
|
||||
if (klass)
|
||||
LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}.", *id, String(klass->GetFullName()));
|
||||
else
|
||||
LOG(Warning, "Unable to find scripting object with ID={0}", *id);
|
||||
|
||||
if (!skipLog)
|
||||
{
|
||||
if (klass)
|
||||
LOG(Warning, "Unable to find scripting object with ID={0}. Required type {1}. {2}", *id, String(klass->GetFullName()), LogContext::GetInfo());
|
||||
else
|
||||
LOG(Warning, "Unable to find scripting object with ID={0}", *id);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user