diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp index 99492c268..a986ded17 100644 --- a/Source/Engine/Scripting/Scripting.cpp +++ b/Source/Engine/Scripting/Scripting.cpp @@ -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; } diff --git a/Source/Engine/Scripting/Scripting.h b/Source/Engine/Scripting/Scripting.h index 19de2684e..52b532795 100644 --- a/Source/Engine/Scripting/Scripting.h +++ b/Source/Engine/Scripting/Scripting.h @@ -133,9 +133,9 @@ public: /// Finds the object by the given identifier. Searches registered scene objects and optionally assets. Logs warning if fails. /// /// The object unique identifier. - /// The type of the object to find. + /// The type of the object to find (optional). /// The found object or null if missing. - static ScriptingObject* FindObject(Guid id, MClass* type); + static ScriptingObject* FindObject(Guid id, MClass* type = nullptr); /// /// Tries to find the object by the given identifier. @@ -152,9 +152,9 @@ public: /// Tries to find the object by the given identifier. /// /// The object unique identifier. - /// The type of the object to find. + /// The type of the object to find (optional). /// The found object or null if missing. - static ScriptingObject* TryFindObject(Guid id, MClass* type); + static ScriptingObject* TryFindObject(Guid id, MClass* type = nullptr); /// /// Finds the object by the given managed instance handle. Searches only registered scene objects. diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index a66b8a103..34e5735cb 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -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; } diff --git a/Source/Engine/Scripting/ScriptingObject.h b/Source/Engine/Scripting/ScriptingObject.h index 1d2365d64..01dd84232 100644 --- a/Source/Engine/Scripting/ScriptingObject.h +++ b/Source/Engine/Scripting/ScriptingObject.h @@ -62,7 +62,6 @@ public: /// /// Gets the managed instance object. /// - /// The Mono managed object or null if not created. MonoObject* GetManagedInstance() const; /// @@ -131,6 +130,7 @@ public: /// The destination class to the cast. /// True if can, otherwise false. static bool CanCast(MClass* from, MClass* to); + static bool CanCast(MClass* from, MonoClass* to); template static T* Cast(ScriptingObject* obj) @@ -145,6 +145,11 @@ public: return CanCast(GetClass(), type); } + bool Is(MonoClass* klass) const + { + return CanCast(GetClass(), klass); + } + template bool Is() const {