diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index f2b07bcb9..52ebbd443 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -75,7 +75,7 @@ MClass* ScriptingObject::GetClass() const return _type ? _type.GetType().ManagedClass : nullptr; } -ScriptingObject* ScriptingObject::FromInterface(void* interfaceObj, ScriptingTypeHandle& interfaceType) +ScriptingObject* ScriptingObject::FromInterface(void* interfaceObj, const ScriptingTypeHandle& interfaceType) { if (!interfaceObj || !interfaceType) return nullptr; @@ -120,6 +120,30 @@ ScriptingObject* ScriptingObject::FromInterface(void* interfaceObj, ScriptingTyp return nullptr; } +void* ScriptingObject::ToInterface(ScriptingObject* obj, const ScriptingTypeHandle& interfaceType) +{ + if (!obj || !interfaceType) + return nullptr; + const ScriptingType& objectType = obj->GetType(); + const ScriptingType::InterfaceImplementation* interface = objectType.GetInterface(interfaceType); + void* result = nullptr; + if (interface && interface->IsNative) + { + // Native interface so just offset pointer to the interface vtable start + result = (byte*)obj + interface->VTableOffset; + } + else if (interface) + { + // Interface implemented in scripting (eg. C# class inherits C++ interface) + if (!ScriptingObjectsInterfaceWrappers.TryGet(obj, result)) + { + result = interfaceType.GetType().Interface.GetInterfaceWrapper(obj); + ScriptingObjectsInterfaceWrappers.Add(obj, result); + } + } + return result; +} + ScriptingObject* ScriptingObject::ToNative(MonoObject* obj) { ScriptingObject* ptr = nullptr; @@ -632,24 +656,7 @@ public: const ScriptingTypeHandle interfaceType = ManagedBinaryModule::FindType(typeClass); if (interfaceType) { - const ScriptingType& objectType = obj->GetType(); - const ScriptingType::InterfaceImplementation* interface = objectType.GetInterface(interfaceType); - if (interface && interface->IsNative) - { - // Native interface so just offset pointer to the interface vtable start - return (byte*)obj + interface->VTableOffset; - } - if (interface) - { - // Interface implemented in scripting (eg. C# class inherits C++ interface) - void* result; - if (!ScriptingObjectsInterfaceWrappers.TryGet(obj, result)) - { - result = interfaceType.GetType().Interface.GetInterfaceWrapper(obj); - ScriptingObjectsInterfaceWrappers.Add(obj, result); - } - return result; - } + return ScriptingObject::ToInterface(obj, interfaceType); } } return nullptr; diff --git a/Source/Engine/Scripting/ScriptingObject.h b/Source/Engine/Scripting/ScriptingObject.h index c33a9dc93..01d4eb33c 100644 --- a/Source/Engine/Scripting/ScriptingObject.h +++ b/Source/Engine/Scripting/ScriptingObject.h @@ -109,7 +109,14 @@ public: public: // Tries to cast native interface object to scripting object instance. Returns null if fails. - static ScriptingObject* FromInterface(void* interfaceObj, ScriptingTypeHandle& interfaceType); + static ScriptingObject* FromInterface(void* interfaceObj, const ScriptingTypeHandle& interfaceType); + static void* ToInterface(ScriptingObject* obj, const ScriptingTypeHandle& interfaceType); + template + static T* ToInterface(ScriptingObject* obj) + { + return (T*)ToInterface(obj, T::TypeInitializer); + } + static ScriptingObject* ToNative(MonoObject* obj); static MonoObject* ToManaged(ScriptingObject* obj)