Merge branch 'marshalling_scriptingobject_changes' of https://github.com/GoaLitiuM/FlaxEngine into GoaLitiuM-marshalling_scriptingobject_changes
# Conflicts: # Source/Engine/Engine/NativeInterop.Unmanaged.cs # Source/Engine/Scripting/Runtime/DotNet.cpp
This commit is contained in:
@@ -51,6 +51,15 @@ public:
|
||||
/// <param name="name">The assembly name.</param>
|
||||
MAssembly(MDomain* domain, const StringAnsiView& name);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MAssembly"/> class.
|
||||
/// </summary>
|
||||
/// <param name="domain">The assembly domain.</param>
|
||||
/// <param name="name">The assembly name.</param>
|
||||
/// <param name="fullname">The assembly full name.</param>
|
||||
/// <param name="handle">The managed handle of the assembly.</param>
|
||||
MAssembly(MDomain* domain, const StringAnsiView& name, const StringAnsiView& fullname, void* handle);
|
||||
|
||||
/// <summary>
|
||||
/// Finalizes an instance of the <see cref="MAssembly"/> class.
|
||||
/// </summary>
|
||||
|
||||
@@ -48,6 +48,18 @@ MAssembly::MAssembly(MDomain* domain, const StringAnsiView& name)
|
||||
{
|
||||
}
|
||||
|
||||
MAssembly::MAssembly(MDomain* domain, const StringAnsiView& name, const StringAnsiView& fullname, void* handle)
|
||||
: _domain(domain)
|
||||
, _isLoaded(false)
|
||||
, _isLoading(false)
|
||||
, _hasCachedClasses(false)
|
||||
, _reloadCount(0)
|
||||
, _name(name)
|
||||
, _fullname(fullname)
|
||||
, _handle(handle)
|
||||
{
|
||||
}
|
||||
|
||||
MAssembly::~MAssembly()
|
||||
{
|
||||
Unload();
|
||||
|
||||
@@ -190,4 +190,13 @@ public:
|
||||
static MClass* Double;
|
||||
static MClass* String;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Utilities for ScriptingObject management.
|
||||
/// </summary>
|
||||
struct FLAXENGINE_API ScriptingObject
|
||||
{
|
||||
static void SetInternalValues(MObject* object, void* unmanagedPtr, const Guid* id);
|
||||
static MObject* CreateScriptingObject(MClass* klass, void* unmanagedPtr, const Guid* id);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ protected:
|
||||
#elif USE_NETCORE
|
||||
void* _handle;
|
||||
void* _type;
|
||||
int32 _fieldOffset;
|
||||
#endif
|
||||
|
||||
MClass* _parentClass;
|
||||
@@ -35,7 +36,7 @@ public:
|
||||
#if USE_MONO
|
||||
explicit MField(MonoClassField* monoField, const char* name, MClass* parentClass);
|
||||
#elif USE_NETCORE
|
||||
MField(MClass* parentClass, void* handle, const char* name, void* type, MFieldAttributes attributes);
|
||||
MField(MClass* parentClass, void* handle, const char* name, void* type, int fieldOffset, MFieldAttributes attributes);
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -102,6 +103,16 @@ public:
|
||||
/// <param name="result">The return value of undefined type.</param>
|
||||
void GetValue(MObject* instance, void* result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Value will be a pointer.
|
||||
/// </remarks>
|
||||
/// <param name="instance">The object of given type to get value from.</param>
|
||||
/// <param name="result">The return value of undefined type.</param>
|
||||
void GetValueReference(MObject* instance, void* result) const;
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves value currently set in the field on the specified object instance. If field is static object instance can be null. If returned value is a value type it will be boxed.
|
||||
/// </summary>
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace FlaxEngine
|
||||
// Construct missing native object if managed objects gets created in managed world
|
||||
if (__unmanagedPtr == IntPtr.Zero)
|
||||
{
|
||||
Internal_ManagedInstanceCreated(this);
|
||||
Internal_ManagedInstanceCreated(this, FlaxEngine.Interop.NativeInterop.GetTypeHolder(GetType()).managedClassPointer);
|
||||
if (__unmanagedPtr == IntPtr.Zero)
|
||||
throw new Exception($"Failed to create native instance for object of type {GetType().FullName} (assembly: {GetType().Assembly.FullName}).");
|
||||
}
|
||||
@@ -320,7 +320,7 @@ namespace FlaxEngine
|
||||
internal static partial Object Internal_Create2(string typeName);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial void Internal_ManagedInstanceCreated(Object managedInstance);
|
||||
internal static partial void Internal_ManagedInstanceCreated(Object managedInstance, IntPtr theKlass);
|
||||
|
||||
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
|
||||
internal static partial void Internal_ManagedInstanceDeleted(IntPtr nativeInstance);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "Engine/Platform/Platform.h"
|
||||
#include "Engine/Platform/File.h"
|
||||
#include "Engine/Platform/FileSystem.h"
|
||||
#include "Engine/Scripting/Internal/InternalCalls.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MCore.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MAssembly.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||
@@ -214,6 +215,7 @@ void* GetCustomAttribute(const MClass* klass, const MClass* attributeClass);
|
||||
struct NativeClassDefinitions
|
||||
{
|
||||
void* typeHandle;
|
||||
MClass* nativePointer;
|
||||
const char* name;
|
||||
const char* fullname;
|
||||
const char* namespace_;
|
||||
@@ -233,6 +235,7 @@ struct NativeFieldDefinitions
|
||||
const char* name;
|
||||
void* fieldHandle;
|
||||
void* fieldType;
|
||||
int fieldOffset;
|
||||
MFieldAttributes fieldAttributes;
|
||||
};
|
||||
|
||||
@@ -341,8 +344,8 @@ void MCore::Object::Init(MObject* obj)
|
||||
MClass* MCore::Object::GetClass(MObject* obj)
|
||||
{
|
||||
ASSERT(obj);
|
||||
MType* typeHandle = GetObjectType(obj);
|
||||
return GetOrCreateClass(typeHandle);
|
||||
static void* GetObjectClassPtr = GetStaticMethodPointer(TEXT("GetObjectClass"));
|
||||
return (MClass*)CallStaticMethod<MClass*, void*>(GetObjectClassPtr, obj);
|
||||
}
|
||||
|
||||
MString* MCore::Object::ToString(MObject* obj)
|
||||
@@ -574,8 +577,7 @@ MObject* MCore::Exception::GetNotSupported(const char* msg)
|
||||
MClass* MCore::Type::GetClass(MType* type)
|
||||
{
|
||||
static void* GetTypeClassPtr = GetStaticMethodPointer(TEXT("GetTypeClass"));
|
||||
type = (MType*)CallStaticMethod<void*, void*>(GetTypeClassPtr, type);
|
||||
return GetOrCreateClass(type);
|
||||
return CallStaticMethod<MClass*, void*>(GetTypeClassPtr, type);
|
||||
}
|
||||
|
||||
MType* MCore::Type::GetElementType(MType* type)
|
||||
@@ -640,10 +642,16 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
|
||||
MClass* klass = New<MClass>(this, managedClass.typeHandle, managedClass.name, managedClass.fullname, managedClass.namespace_, managedClass.typeAttributes);
|
||||
_classes.Add(klass->GetFullName(), klass);
|
||||
|
||||
managedClass.nativePointer = klass;
|
||||
|
||||
MCore::GC::FreeMemory((void*)managedClasses[i].name);
|
||||
MCore::GC::FreeMemory((void*)managedClasses[i].fullname);
|
||||
MCore::GC::FreeMemory((void*)managedClasses[i].namespace_);
|
||||
}
|
||||
|
||||
static void* RegisterManagedClassNativePointersPtr = GetStaticMethodPointer(TEXT("RegisterManagedClassNativePointers"));
|
||||
CallStaticMethod<void, NativeClassDefinitions**, int>(RegisterManagedClassNativePointersPtr, &managedClasses, classCount);
|
||||
|
||||
MCore::GC::FreeMemory(managedClasses);
|
||||
|
||||
const auto endTime = DateTime::NowUTC();
|
||||
@@ -658,6 +666,39 @@ const MAssembly::ClassesDictionary& MAssembly::GetClasses() const
|
||||
return _classes;
|
||||
}
|
||||
|
||||
void GetAssemblyName(void* assemblyHandle, StringAnsi& name, StringAnsi& fullname)
|
||||
{
|
||||
static void* GetAssemblyNamePtr = GetStaticMethodPointer(TEXT("GetAssemblyName"));
|
||||
const char* name_;
|
||||
const char* fullname_;
|
||||
CallStaticMethod<void, void*, const char**, const char**>(GetAssemblyNamePtr, assemblyHandle, &name_, &fullname_);
|
||||
name = name_;
|
||||
fullname = fullname_;
|
||||
MCore::GC::FreeMemory((void*)name_);
|
||||
MCore::GC::FreeMemory((void*)fullname_);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) NativeInterop_CreateClass(NativeClassDefinitions* managedClass, void* assemblyHandle)
|
||||
{
|
||||
MAssembly* assembly = GetAssembly(assemblyHandle);
|
||||
if (assembly == nullptr)
|
||||
{
|
||||
StringAnsi assemblyName;
|
||||
StringAnsi assemblyFullName;
|
||||
GetAssemblyName(assemblyHandle, assemblyName, assemblyFullName);
|
||||
|
||||
assembly = New<MAssembly>(nullptr, assemblyName, assemblyFullName, assemblyHandle);
|
||||
CachedAssemblyHandles.Add(assemblyHandle, assembly);
|
||||
}
|
||||
|
||||
MClass* klass = New<MClass>(assembly, managedClass->typeHandle, managedClass->name, managedClass->fullname, managedClass->namespace_, managedClass->typeAttributes);
|
||||
if (assembly != nullptr)
|
||||
{
|
||||
const_cast<MAssembly::ClassesDictionary&>(assembly->GetClasses()).Add(klass->GetFullName(), klass);
|
||||
}
|
||||
managedClass->nativePointer = klass;
|
||||
}
|
||||
|
||||
bool MAssembly::LoadCorlib()
|
||||
{
|
||||
if (IsLoaded())
|
||||
@@ -677,14 +718,9 @@ bool MAssembly::LoadCorlib()
|
||||
|
||||
// Load
|
||||
{
|
||||
const char* name;
|
||||
const char* fullname;
|
||||
static void* GetAssemblyByNamePtr = GetStaticMethodPointer(TEXT("GetAssemblyByName"));
|
||||
_handle = CallStaticMethod<void*, const char*, const char**, const char**>(GetAssemblyByNamePtr, "System.Private.CoreLib", &name, &fullname);
|
||||
_name = name;
|
||||
_fullname = fullname;
|
||||
MCore::GC::FreeMemory((void*)name);
|
||||
MCore::GC::FreeMemory((void*)fullname);
|
||||
_handle = CallStaticMethod<void*, const char*>(GetAssemblyByNamePtr, "System.Private.CoreLib");
|
||||
GetAssemblyName(_handle, _name, _fullname);
|
||||
}
|
||||
if (_handle == nullptr)
|
||||
{
|
||||
@@ -703,19 +739,14 @@ bool MAssembly::LoadImage(const String& assemblyPath, const StringView& nativePa
|
||||
{
|
||||
// TODO: Use new hostfxr delegate load_assembly_bytes? (.NET 8+)
|
||||
// Open .Net assembly
|
||||
const char* name = nullptr;
|
||||
const char* fullname = nullptr;
|
||||
static void* LoadAssemblyImagePtr = GetStaticMethodPointer(TEXT("LoadAssemblyImage"));
|
||||
_handle = CallStaticMethod<void*, const Char*, const char**, const char**>(LoadAssemblyImagePtr, assemblyPath.Get(), &name, &fullname);
|
||||
_name = StringAnsi(name);
|
||||
_fullname = StringAnsi(fullname);
|
||||
MCore::GC::FreeMemory((void*)name);
|
||||
MCore::GC::FreeMemory((void*)fullname);
|
||||
_handle = CallStaticMethod<void*, const Char*>(LoadAssemblyImagePtr, assemblyPath.Get());
|
||||
if (_handle == nullptr)
|
||||
{
|
||||
Log::CLRInnerException(TEXT(".NET assembly image is invalid at ") + assemblyPath);
|
||||
return true;
|
||||
}
|
||||
GetAssemblyName(_handle, _name, _fullname);
|
||||
CachedAssemblyHandles.Add(_handle, this);
|
||||
|
||||
// Provide new path of hot-reloaded native library path for managed DllImport
|
||||
@@ -845,8 +876,7 @@ MType* MClass::GetType() const
|
||||
MClass* MClass::GetBaseClass() const
|
||||
{
|
||||
static void* GetClassParentPtr = GetStaticMethodPointer(TEXT("GetClassParent"));
|
||||
MType* parentTypeHandle = CallStaticMethod<MType*, void*>(GetClassParentPtr, _handle);
|
||||
return GetOrCreateClass(parentTypeHandle);
|
||||
return CallStaticMethod<MClass*, void*>(GetClassParentPtr, _handle);
|
||||
}
|
||||
|
||||
bool MClass::IsSubClassOf(const MClass* klass, bool checkInterfaces) const
|
||||
@@ -881,8 +911,7 @@ uint32 MClass::GetInstanceSize() const
|
||||
MClass* MClass::GetElementClass() const
|
||||
{
|
||||
static void* GetElementClassPtr = GetStaticMethodPointer(TEXT("GetElementClass"));
|
||||
MType* elementTypeHandle = CallStaticMethod<MType*, void*>(GetElementClassPtr, _handle);
|
||||
return GetOrCreateClass(elementTypeHandle);
|
||||
return CallStaticMethod<MClass*, void*>(GetElementClassPtr, _handle);
|
||||
}
|
||||
|
||||
MMethod* MClass::GetMethod(const char* name, int32 numParams) const
|
||||
@@ -941,7 +970,7 @@ const Array<MField*>& MClass::GetFields() const
|
||||
for (int32 i = 0; i < numFields; i++)
|
||||
{
|
||||
NativeFieldDefinitions& definition = fields[i];
|
||||
MField* field = New<MField>(const_cast<MClass*>(this), definition.fieldHandle, definition.name, definition.fieldType, definition.fieldAttributes);
|
||||
MField* field = New<MField>(const_cast<MClass*>(this), definition.fieldHandle, definition.name, definition.fieldType, definition.fieldOffset, definition.fieldAttributes);
|
||||
_fields.Add(field);
|
||||
MCore::GC::FreeMemory((void*)definition.name);
|
||||
}
|
||||
@@ -1022,7 +1051,7 @@ bool MClass::HasAttribute(const MClass* monoClass) const
|
||||
|
||||
bool MClass::HasAttribute() const
|
||||
{
|
||||
return GetCustomAttribute(this, nullptr) != nullptr;
|
||||
return !GetAttributes().IsEmpty();
|
||||
}
|
||||
|
||||
MObject* MClass::GetAttribute(const MClass* monoClass) const
|
||||
@@ -1132,11 +1161,12 @@ MException::~MException()
|
||||
Delete(InnerException);
|
||||
}
|
||||
|
||||
MField::MField(MClass* parentClass, void* handle, const char* name, void* type, MFieldAttributes attributes)
|
||||
MField::MField(MClass* parentClass, void* handle, const char* name, void* type, int fieldOffset, MFieldAttributes attributes)
|
||||
: _handle(handle)
|
||||
, _type(type)
|
||||
, _parentClass(parentClass)
|
||||
, _name(name)
|
||||
, _fieldOffset(fieldOffset)
|
||||
, _hasCachedAttributes(false)
|
||||
{
|
||||
switch (attributes & MFieldAttributes::FieldAccessMask)
|
||||
@@ -1172,8 +1202,7 @@ MType* MField::GetType() const
|
||||
|
||||
int32 MField::GetOffset() const
|
||||
{
|
||||
static void* FieldGetOffsetPtr = GetStaticMethodPointer(TEXT("FieldGetOffset"));
|
||||
return CallStaticMethod<int32, void*>(FieldGetOffsetPtr, _handle);
|
||||
return _fieldOffset;
|
||||
}
|
||||
|
||||
void MField::GetValue(MObject* instance, void* result) const
|
||||
@@ -1182,6 +1211,12 @@ void MField::GetValue(MObject* instance, void* result) const
|
||||
CallStaticMethod<void, void*, void*, void*>(FieldGetValuePtr, instance, _handle, result);
|
||||
}
|
||||
|
||||
void MField::GetValueReference(MObject* instance, void* result) const
|
||||
{
|
||||
static void* FieldGetValueReferencePtr = GetStaticMethodPointer(TEXT("FieldGetValueReferenceWithOffset"));
|
||||
CallStaticMethod<void, void*, int, void*>(FieldGetValueReferencePtr, instance, _fieldOffset, result);
|
||||
}
|
||||
|
||||
MObject* MField::GetValueBoxed(MObject* instance) const
|
||||
{
|
||||
static void* FieldGetValueBoxedPtr = GetStaticMethodPointer(TEXT("FieldGetValueBoxed"));
|
||||
@@ -1514,8 +1549,7 @@ void* GetCustomAttribute(const MClass* klass, const MClass* attributeClass)
|
||||
const Array<MObject*>& attributes = klass->GetAttributes();
|
||||
for (MObject* attr : attributes)
|
||||
{
|
||||
MType* typeHandle = GetObjectType(attr);
|
||||
MClass* attrClass = GetOrCreateClass(typeHandle);
|
||||
MClass* attrClass = MCore::Object::GetClass(attr);
|
||||
if (attrClass == attributeClass)
|
||||
return attr;
|
||||
}
|
||||
@@ -1703,6 +1737,18 @@ void* GetStaticMethodPointer(const String& methodName)
|
||||
return fun;
|
||||
}
|
||||
|
||||
void MCore::ScriptingObject::SetInternalValues(MObject* object, void* unmanagedPtr, const Guid* id)
|
||||
{
|
||||
static void* ScriptingObjectSetInternalValuesPtr = GetStaticMethodPointer(TEXT("ScriptingObjectSetInternalValues"));
|
||||
CallStaticMethod<void, MObject*, void*, const Guid*>(ScriptingObjectSetInternalValuesPtr, object, unmanagedPtr, id);
|
||||
}
|
||||
|
||||
MObject* MCore::ScriptingObject::CreateScriptingObject(MClass* klass, void* unmanagedPtr, const Guid* id)
|
||||
{
|
||||
static void* ScriptingObjectSetInternalValuesPtr = GetStaticMethodPointer(TEXT("ScriptingObjectCreate"));
|
||||
return CallStaticMethod<MObject*, void*, void*, const Guid*>(ScriptingObjectSetInternalValuesPtr, klass->_handle, unmanagedPtr, id);
|
||||
}
|
||||
|
||||
#elif DOTNET_HOST_MONO
|
||||
|
||||
#ifdef USE_MONO_AOT_MODULE
|
||||
|
||||
@@ -2127,6 +2127,15 @@ const Array<MObject*>& MProperty::GetAttributes() const
|
||||
return _attributes;
|
||||
}
|
||||
|
||||
void MCore::ScriptingObject::SetInternalValues(MObject* object, void* unmanagedPtr, const Guid* id)
|
||||
{
|
||||
}
|
||||
|
||||
MObject* MCore::ScriptingObject::CreateScriptingObject(MClass* klass, void* unmanagedPtr, const Guid* id)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if USE_MONO && PLATFORM_WIN32 && !USE_MONO_DYNAMIC_LIB
|
||||
|
||||
@@ -565,4 +565,13 @@ const Array<MObject*>& MProperty::GetAttributes() const
|
||||
return _attributes;
|
||||
}
|
||||
|
||||
void MCore::ScriptingObject::SetInternalValues(MObject* object, void* unmanagedPtr, const Guid* id)
|
||||
{
|
||||
}
|
||||
|
||||
MObject* MCore::ScriptingObject::CreateScriptingObject(MClass* klass, void* unmanagedPtr, const Guid* id)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -180,10 +180,15 @@ ScriptingObject* ScriptingObject::ToNative(MObject* obj)
|
||||
#if USE_CSHARP
|
||||
if (obj)
|
||||
{
|
||||
#if USE_MONO
|
||||
// TODO: cache the field offset from object and read directly from object pointer
|
||||
const auto ptrField = MCore::Object::GetClass(obj)->GetField(ScriptingObject_unmanagedPtr);
|
||||
CHECK_RETURN(ptrField, nullptr);
|
||||
ptrField->GetValue(obj, &ptr);
|
||||
#else
|
||||
static const MField* ptrField = MCore::Object::GetClass(obj)->GetField(ScriptingObject_unmanagedPtr);
|
||||
ptrField->GetValueReference(obj, &ptr);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return ptr;
|
||||
@@ -274,12 +279,7 @@ bool ScriptingObject::CreateManaged()
|
||||
if (const auto monoClass = GetClass())
|
||||
{
|
||||
// Reset managed to unmanaged pointer
|
||||
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
|
||||
if (monoUnmanagedPtrField)
|
||||
{
|
||||
void* param = nullptr;
|
||||
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
||||
}
|
||||
SetInternalValues(monoClass, managedInstance, nullptr, nullptr);
|
||||
}
|
||||
MCore::GCHandle::Free(handle);
|
||||
return true;
|
||||
@@ -295,6 +295,32 @@ bool ScriptingObject::CreateManaged()
|
||||
|
||||
#if USE_CSHARP
|
||||
|
||||
void ScriptingObject::SetInternalValues(MClass* monoClass, MObject* managedInstance, void* unmanagedPtr, const Guid* id)
|
||||
{
|
||||
#if USE_MONO
|
||||
// Set handle to unmanaged object
|
||||
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
|
||||
if (monoUnmanagedPtrField)
|
||||
{
|
||||
const void* param = unmanagedPtr;
|
||||
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
||||
}
|
||||
|
||||
if (id != nullptr)
|
||||
{
|
||||
// Set object id
|
||||
const MField* monoIdField = monoClass->GetField(ScriptingObject_id);
|
||||
if (monoIdField)
|
||||
{
|
||||
monoIdField->SetValue(managedInstance, (void*)id);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
MCore::ScriptingObject::SetInternalValues(managedInstance, unmanagedPtr, id);
|
||||
#endif
|
||||
}
|
||||
|
||||
MObject* ScriptingObject::CreateManagedInternal()
|
||||
{
|
||||
// Get class
|
||||
@@ -308,6 +334,7 @@ MObject* ScriptingObject::CreateManagedInternal()
|
||||
// Ensure to have managed domain attached (this can be called from custom native thread, eg. content loader)
|
||||
MCore::Thread::Attach();
|
||||
|
||||
#if USE_MONO
|
||||
// Allocate managed instance
|
||||
MObject* managedInstance = MCore::Object::New(monoClass);
|
||||
if (managedInstance == nullptr)
|
||||
@@ -315,23 +342,17 @@ MObject* ScriptingObject::CreateManagedInternal()
|
||||
LOG(Warning, "Failed to create new instance of the object of type {0}", String(monoClass->GetFullName()));
|
||||
}
|
||||
|
||||
// Set handle to unmanaged object
|
||||
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
|
||||
if (monoUnmanagedPtrField)
|
||||
{
|
||||
const void* value = this;
|
||||
monoUnmanagedPtrField->SetValue(managedInstance, &value);
|
||||
}
|
||||
|
||||
// Set object id
|
||||
const MField* monoIdField = monoClass->GetField(ScriptingObject_id);
|
||||
if (monoIdField)
|
||||
{
|
||||
monoIdField->SetValue(managedInstance, (void*)&_id);
|
||||
}
|
||||
SetInternalValues(monoClass, managedInstance, this, &_id);
|
||||
|
||||
// Initialize managed instance (calls constructor)
|
||||
MCore::Object::Init(managedInstance);
|
||||
#else
|
||||
MObject* managedInstance = MCore::ScriptingObject::CreateScriptingObject(monoClass, this, &_id);
|
||||
if (managedInstance == nullptr)
|
||||
{
|
||||
LOG(Warning, "Failed to create new instance of the object of type {0}", String(monoClass->GetFullName()));
|
||||
}
|
||||
#endif
|
||||
|
||||
return managedInstance;
|
||||
}
|
||||
@@ -349,12 +370,7 @@ void ScriptingObject::DestroyManaged()
|
||||
{
|
||||
if (const auto monoClass = GetClass())
|
||||
{
|
||||
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
|
||||
if (monoUnmanagedPtrField)
|
||||
{
|
||||
void* param = nullptr;
|
||||
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
||||
}
|
||||
SetInternalValues(monoClass, managedInstance, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -478,12 +494,7 @@ bool ManagedScriptingObject::CreateManaged()
|
||||
if (const auto monoClass = GetClass())
|
||||
{
|
||||
// Reset managed to unmanaged pointer
|
||||
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
|
||||
if (monoUnmanagedPtrField)
|
||||
{
|
||||
void* param = nullptr;
|
||||
monoUnmanagedPtrField->SetValue(managedInstance, ¶m);
|
||||
}
|
||||
SetInternalValues(monoClass, managedInstance, nullptr, nullptr);
|
||||
}
|
||||
MCore::GCHandle::Free(handle);
|
||||
return true;
|
||||
@@ -605,10 +616,8 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(MString* typeNameObj)
|
||||
return managedInstance;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MObject* managedInstance)
|
||||
DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MObject* managedInstance, MClass* typeClass)
|
||||
{
|
||||
MClass* typeClass = MCore::Object::GetClass(managedInstance);
|
||||
|
||||
// Get the assembly with that class
|
||||
auto module = ManagedBinaryModule::FindModule(typeClass);
|
||||
if (module == nullptr)
|
||||
@@ -646,21 +655,8 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_ManagedInstanceCreated(MObject* manage
|
||||
|
||||
MClass* monoClass = obj->GetClass();
|
||||
|
||||
// Set handle to unmanaged object
|
||||
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
|
||||
if (monoUnmanagedPtrField)
|
||||
{
|
||||
const void* value = obj;
|
||||
monoUnmanagedPtrField->SetValue(managedInstance, &value);
|
||||
}
|
||||
|
||||
// Set object id
|
||||
const MField* monoIdField = monoClass->GetField(ScriptingObject_id);
|
||||
if (monoIdField)
|
||||
{
|
||||
const Guid id = obj->GetID();
|
||||
monoIdField->SetValue(managedInstance, (void*)&id);
|
||||
}
|
||||
const Guid id = obj->GetID();
|
||||
ScriptingObject::SetInternalValues(monoClass, managedInstance, obj, &id);
|
||||
|
||||
// Register object
|
||||
if (!obj->IsRegistered())
|
||||
|
||||
@@ -206,6 +206,13 @@ public:
|
||||
/// </summary>
|
||||
void UnregisterObject();
|
||||
|
||||
#if USE_CSHARP
|
||||
/// <summary>
|
||||
/// Sets the internal values in managed object.
|
||||
/// </summary>
|
||||
static void SetInternalValues(MClass* monoClass, MObject* managedInstance, void* unmanagedPtr, const Guid* id);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#if USE_CSHARP
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user