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)
{
// Check type
if (result->Is(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()));
return nullptr;
}
// 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()))
{
Asset* asset = Content::LoadAsync(id, type);
@@ -796,7 +803,7 @@ ScriptingObject* Scripting::TryFindObject(Guid id, MClass* type)
#endif
// Check type
if (result && !result->Is(type))
if (result && type && !result->Is(type))
{
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.
/// </summary>
/// <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>
static ScriptingObject* FindObject(Guid id, MClass* type);
static ScriptingObject* FindObject(Guid id, MClass* type = nullptr);
/// <summary>
/// Tries to find the object by the given identifier.
@@ -152,9 +152,9 @@ public:
/// Tries to find the object by the given identifier.
/// </summary>
/// <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>
static ScriptingObject* TryFindObject(Guid id, MClass* type);
static ScriptingObject* TryFindObject(Guid id, MClass* type = nullptr);
/// <summary>
/// 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);
}
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()
{
// Cleanup managed object
@@ -542,13 +556,17 @@ public:
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;
}
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;
}

View File

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