Optimize FindObject and TryFindObject in Object

This commit is contained in:
Wojtek Figat
2021-08-10 15:57:22 +02:00
parent 62c43f9f95
commit 27f2856e6d
4 changed files with 39 additions and 9 deletions

View File

@@ -754,13 +754,20 @@ ScriptingObject* Scripting::FindObject(Guid id, MClass* type)
if (result) if (result)
{ {
// Check type // Check type
if (result->Is(type)) if (!type || result->Is(type))
return result; 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}.", id, String(result->GetType().Fullname), String(type->GetFullName()));
return nullptr; return nullptr;
} }
// Check if object can be an asset and try to load it // Check if object can be an asset and try to load it
if (!type)
{
result = Content::LoadAsync(id, Asset::GetStaticClass());
if (!result)
LOG(Warning, "Unable to find scripting object with ID={0}", id);
return result;
}
if (type == ScriptingObject::GetStaticClass() || type->IsSubClassOf(Asset::GetStaticClass())) if (type == ScriptingObject::GetStaticClass() || type->IsSubClassOf(Asset::GetStaticClass()))
{ {
Asset* asset = Content::LoadAsync(id, type); Asset* asset = Content::LoadAsync(id, type);
@@ -796,7 +803,7 @@ ScriptingObject* Scripting::TryFindObject(Guid id, MClass* type)
#endif #endif
// Check type // Check type
if (result && !result->Is(type)) if (result && type && !result->Is(type))
{ {
result = nullptr; result = nullptr;
} }

View File

@@ -133,9 +133,9 @@ public:
/// Finds the object by the given identifier. Searches registered scene objects and optionally assets. Logs warning if fails. /// Finds the object by the given identifier. Searches registered scene objects and optionally assets. Logs warning if fails.
/// </summary> /// </summary>
/// <param name="id">The object unique identifier.</param> /// <param name="id">The object unique identifier.</param>
/// <param name="type">The type of the object to find.</param> /// <param name="type">The type of the object to find (optional).</param>
/// <returns>The found object or null if missing.</returns> /// <returns>The found object or null if missing.</returns>
static ScriptingObject* FindObject(Guid id, MClass* type); static ScriptingObject* FindObject(Guid id, MClass* type = nullptr);
/// <summary> /// <summary>
/// Tries to find the object by the given identifier. /// Tries to find the object by the given identifier.
@@ -152,9 +152,9 @@ public:
/// Tries to find the object by the given identifier. /// Tries to find the object by the given identifier.
/// </summary> /// </summary>
/// <param name="id">The object unique identifier.</param> /// <param name="id">The object unique identifier.</param>
/// <param name="type">The type of the object to find.</param> /// <param name="type">The type of the object to find (optional).</param>
/// <returns>The found object or null if missing.</returns> /// <returns>The found object or null if missing.</returns>
static ScriptingObject* TryFindObject(Guid id, MClass* type); static ScriptingObject* TryFindObject(Guid id, MClass* type = nullptr);
/// <summary> /// <summary>
/// Finds the object by the given managed instance handle. Searches only registered scene objects. /// Finds the object by the given managed instance handle. Searches only registered scene objects.

View File

@@ -244,6 +244,20 @@ bool ScriptingObject::CanCast(MClass* from, MClass* to)
return from->IsSubClassOf(to); return from->IsSubClassOf(to);
} }
bool ScriptingObject::CanCast(MClass* from, MonoClass* to)
{
if (!from && !to)
return true;
CHECK_RETURN(from && to, false);
#if PLATFORM_LINUX
// Cannot enter GC unsafe region if the thread is not attached
MCore::AttachThread();
#endif
return from->IsSubClassOf(to);
}
void ScriptingObject::OnDeleteObject() void ScriptingObject::OnDeleteObject()
{ {
// Cleanup managed object // Cleanup managed object
@@ -542,13 +556,17 @@ public:
static MonoObject* FindObject(Guid* id, MonoReflectionType* type) static MonoObject* FindObject(Guid* id, MonoReflectionType* type)
{ {
ScriptingObject* obj = Scripting::FindObject(*id, Scripting::FindClass(MUtils::GetClass(type))); ScriptingObject* obj = Scripting::FindObject(*id);
if (obj && !obj->Is(MUtils::GetClass(type)))
obj = nullptr;
return obj ? obj->GetOrCreateManagedInstance() : nullptr; return obj ? obj->GetOrCreateManagedInstance() : nullptr;
} }
static MonoObject* TryFindObject(Guid* id, MonoReflectionType* type) static MonoObject* TryFindObject(Guid* id, MonoReflectionType* type)
{ {
ScriptingObject* obj = Scripting::TryFindObject(*id, Scripting::FindClass(MUtils::GetClass(type))); ScriptingObject* obj = Scripting::TryFindObject(*id);
if (obj && !obj->Is(MUtils::GetClass(type)))
obj = nullptr;
return obj ? obj->GetOrCreateManagedInstance() : nullptr; return obj ? obj->GetOrCreateManagedInstance() : nullptr;
} }

View File

@@ -62,7 +62,6 @@ public:
/// <summary> /// <summary>
/// Gets the managed instance object. /// Gets the managed instance object.
/// </summary> /// </summary>
/// <returns>The Mono managed object or null if not created.</returns>
MonoObject* GetManagedInstance() const; MonoObject* GetManagedInstance() const;
/// <summary> /// <summary>
@@ -131,6 +130,7 @@ public:
/// <param name="to">The destination class to the cast.</param> /// <param name="to">The destination class to the cast.</param>
/// <returns>True if can, otherwise false.</returns> /// <returns>True if can, otherwise false.</returns>
static bool CanCast(MClass* from, MClass* to); static bool CanCast(MClass* from, MClass* to);
static bool CanCast(MClass* from, MonoClass* to);
template<typename T> template<typename T>
static T* Cast(ScriptingObject* obj) static T* Cast(ScriptingObject* obj)
@@ -145,6 +145,11 @@ public:
return CanCast(GetClass(), type); return CanCast(GetClass(), type);
} }
bool Is(MonoClass* klass) const
{
return CanCast(GetClass(), klass);
}
template<typename T> template<typename T>
bool Is() const bool Is() const
{ {