initial nativestring and nativearray marshalling
Some checks failed
Build Android / Game (Android, Release ARM64) (push) Has been cancelled
Build iOS / Game (iOS, Release ARM64) (push) Has been cancelled
Build Linux / Editor (Linux, Development x64) (push) Has been cancelled
Build Linux / Game (Linux, Release x64) (push) Has been cancelled
Build macOS / Editor (Mac, Development ARM64) (push) Has been cancelled
Build macOS / Game (Mac, Release ARM64) (push) Has been cancelled
Build Windows / Editor (Windows, Development x64) (push) Has been cancelled
Build Windows / Game (Windows, Release x64) (push) Has been cancelled
Cooker / Cook (Mac) (push) Has been cancelled
Tests / Tests (Linux) (push) Has been cancelled
Tests / Tests (Windows) (push) Has been cancelled

This commit is contained in:
2026-01-03 16:00:55 +02:00
parent c7326ea483
commit 7088ce8742
25 changed files with 1958 additions and 341 deletions

View File

@@ -35,6 +35,11 @@ DEFINE_INTERNAL_CALL(MObject*) UtilsInternal_ExtractArrayFromList(MObject* obj)
}
#endif
//#if USE_NETCORE
//APgI_TYPEDEF() typedef MString* ManagedString;
API_TYPEDEF() typedef String* ManagedString;
//#endif
DEFINE_INTERNAL_CALL(void) PlatformInternal_MemoryCopy(void* dst, const void* src, uint64 size)
{
Platform::MemoryCopy(dst, src, size);
@@ -50,24 +55,33 @@ DEFINE_INTERNAL_CALL(int32) PlatformInternal_MemoryCompare(const void* buf1, con
return Platform::MemoryCompare(buf1, buf2, size);
}
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, MString* msgObj)
{
#if LOG_ENABLE
StringView msg;
MUtils::ToString(msgObj, msg);
Log::Logger::Write(level, msg);
#endif
}
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MString* msgObj, ScriptingObject* obj, MString* stackTrace)
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogWrite(LogType level, ManagedString msgObj)
{
#if LOG_ENABLE
if (msgObj == nullptr)
return;
#if USE_NETCORE
StringView msg(*msgObj);
#else
StringView msg;
MUtils::ToString(msgObj, msg);
#endif
Log::Logger::Write(level, msg);
#endif
}
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, ManagedString msgObj, ScriptingObject* obj, ManagedString stackTrace)
{
#if LOG_ENABLE
if (msgObj == nullptr)
return;
#if USE_NETCORE
StringView msg(*msgObj);
#else
// Get info
StringView msg;
MUtils::ToString(msgObj, msg);
#endif
//const String objName = obj ? obj->ToString() : String::Empty;
// Send event
@@ -79,6 +93,7 @@ DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_Log(LogType level, MString* m
DEFINE_INTERNAL_CALL(void) DebugLogHandlerInternal_LogException(MObject* exception, ScriptingObject* obj)
{
PLATFORM_DEBUG_BREAK;
#if USE_CSHARP
if (exception == nullptr)
return;
@@ -117,11 +132,17 @@ namespace
#endif
}
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(MString* nameObj)
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEvent(ManagedString nameObj)
{
#if COMPILE_WITH_PROFILER
if (nameObj == nullptr)
return;
#if USE_NETCORE
StringView name(*nameObj);
#else
StringView name;
MUtils::ToString(nameObj, name);
#endif
ProfilerCPU::BeginEvent(*name);
#if TRACY_ENABLE
#if PROFILE_CPU_USE_TRANSIENT_DATA
@@ -173,10 +194,16 @@ DEFINE_INTERNAL_CALL(void) ProfilerInternal_EndEvent()
#endif
}
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(MString* nameObj)
DEFINE_INTERNAL_CALL(void) ProfilerInternal_BeginEventGPU(ManagedString nameObj)
{
#if COMPILE_WITH_PROFILER
#if USE_NETCORE
if (nameObj == nullptr)
return;
const StringView nameChars(*nameObj);
#else
const StringView nameChars = MCore::String::GetChars(nameObj);
#endif
const auto index = ProfilerGPU::BeginEvent(nameChars.Get());
ManagedEventsGPU.Push(index);
#endif
@@ -197,6 +224,7 @@ DEFINE_INTERNAL_CALL(bool) ScriptingInternal_HasGameModulesLoaded()
DEFINE_INTERNAL_CALL(bool) ScriptingInternal_IsTypeFromGameScripts(MTypeObject* type)
{
PLATFORM_DEBUG_BREAK;
return Scripting::IsTypeFromGameScripts(MUtils::GetClass(INTERNAL_TYPE_OBJECT_GET(type)));
}

View File

@@ -43,6 +43,7 @@ void ManagedSerialization::Serialize(ISerializable::SerializeStream& stream, MOb
// Write result data
stream.RawValue(MCore::String::GetChars(invokeResultStr));
MCore::String::Free(invokeResultStr);
}
void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream, MObject* object, MObject* other)
@@ -79,6 +80,7 @@ void ManagedSerialization::SerializeDiff(ISerializable::SerializeStream& stream,
// Write result data
stream.RawValue(MCore::String::GetChars(invokeResultStr));
MCore::String::Free(invokeResultStr);
}
void ManagedSerialization::Deserialize(ISerializable::DeserializeStream& stream, MObject* object)

View File

@@ -41,6 +41,118 @@ namespace
}
}
#if USE_NETCORE
StringView MUtils::ToString(MString* str)
{
if (str == nullptr)
return StringView::Empty;
return StringView(*(String*)str);
}
StringAnsi MUtils::ToStringAnsi(MString* str)
{
if (str == nullptr)
return StringAnsi::Empty;
return StringAnsi(*(String*)str);
}
void MUtils::ToString(MString* str, String& result)
{
if (str)
{
const StringView chars = StringView(*(String*)str);
result.Set(chars.Get(), chars.Length());
}
else
result.Clear();
}
void MUtils::ToString(MString* str, StringView& result)
{
if (str)
result = StringView(*(String*)str);
else
result = StringView();
}
void MUtils::ToString(MString* str, Variant& result)
{
result.SetString(str ? StringView(*(String*)str) : StringView::Empty);
}
void MUtils::ToString(MString* str, StringAnsi& result)
{
if (str)
{
const StringView chars = StringView(*(String*)str);
result.Set(chars.Get(), chars.Length());
}
else
result.Clear();
}
MString* MUtils::ToString(const char* str)
{
CRASH;
if (str == nullptr || *str == 0)
return (MString*)(New<String>());
return (MString*)(New<String>(str, StringUtils::Length(str)));
}
MString* MUtils::ToString(const StringAnsi& str)
{
CRASH;
const int32 len = str.Length();
if (len <= 0)
return (MString*)(New<String>());
return (MString*)(New<String>(str.Get(), len));
}
MString* MUtils::ToString(const String& str)
{
CRASH;
const int32 len = str.Length();
if (len <= 0)
return (MString*)(New<String>());
return (MString*)(New<String>(str.Get(), len));
}
MString* MUtils::ToString(const String& str, MDomain* domain)
{
CRASH;
const int32 len = str.Length();
if (len <= 0)
return (MString*)(New<String>());
return (MString*)(New<String>(str.Get(), len));
}
MString* MUtils::ToString(const StringAnsiView& str)
{
CRASH;
const int32 len = str.Length();
if (len <= 0)
return (MString*)(New<String>());
return (MString*)(New<String>(str.Get(), len));
}
MString* MUtils::ToString(const StringView& str)
{
CRASH;
const int32 len = str.Length();
if (len <= 0)
return (MString*)(New<String>());
return (MString*)(New<String>(str.Get(), len));
}
MString* MUtils::ToString(const StringView& str, MDomain* domain)
{
CRASH;
const int32 len = str.Length();
if (len <= 0)
return (MString*)(New<String>());
return (MString*)(New<String>(str.Get(), len));
}
#else
StringView MUtils::ToString(MString* str)
{
if (str == nullptr)
@@ -144,6 +256,7 @@ MString* MUtils::ToString(const StringView& str, MDomain* domain)
return MCore::String::GetEmpty(domain);
return MCore::String::New(str.Get(), len, domain);
}
#endif
ScriptingTypeHandle MUtils::UnboxScriptingTypeHandle(MTypeObject* value)
{

View File

@@ -85,6 +85,41 @@ struct NativeArray
}
};
/// <summary>
/// A simple POD type Span used with interop between managed and unmanaged sides.
/// </summary>
template<typename T>
struct NativeSpan
{
public:
T* Data;
int32 Length;
public:
static NativeSpan<T> AsSpan(T* data, int32 length)
{
return { data, length };
}
};
template<typename T>
NativeSpan<T> ToNativeSpan(const T* data, int32 length)
{
return { data, length };
}
template<typename T>
NativeSpan<T> ToNativeSpan(const Array<T>& array)
{
return { array.Get(), array.Count() };
}
template<typename T>
NativeSpan<T> ToNativeSpan(const Span<T>& span)
{
return { span.Get(), span.Length() };
}
#if USE_NETCORE
// Special case for boolean values, the handles are fixed and should not be removed
template<>
@@ -128,7 +163,7 @@ struct MConverter<bool>
void FreeManagedArray(MArray* array)
{
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
#endif
@@ -176,7 +211,7 @@ struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class
void FreeManagedArray(MArray* array)
{
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -241,12 +276,13 @@ struct MConverter<String>
void FreeManagedArray(MArray* array)
{
PLATFORM_DEBUG_BREAK;
MString** dataPtr = MCore::Array::GetAddress<MString*>(array);
auto length = MCore::Array::GetLength(array);
for (int32 i = 0; i < length; i++)
MCore::String::Free(dataPtr[i]);
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -299,12 +335,13 @@ struct MConverter<StringAnsi>
void FreeManagedArray(MArray* array)
{
PLATFORM_DEBUG_BREAK;
MString** dataPtr = MCore::Array::GetAddress<MString*>(array);
auto length = MCore::Array::GetLength(array);
for (int32 i = 0; i < length; i++)
MCore::String::Free(dataPtr[i]);
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -368,7 +405,7 @@ struct MConverter<StringView>
for (int32 i = 0; i < length; i++)
MCore::String::Free(dataPtr[i]);
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -427,7 +464,7 @@ struct MConverter<Variant>
{
PLATFORM_DEBUG_BREAK; // FIXME
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -485,7 +522,6 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
void FreeManagedArray(MArray* array)
{
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -540,7 +576,7 @@ struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Val
{
PLATFORM_DEBUG_BREAK; // FIXME
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -602,7 +638,7 @@ struct MConverter<ScriptingObjectReference<T>>
{
PLATFORM_DEBUG_BREAK; // FIXME
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -663,7 +699,7 @@ struct MConverter<AssetReference<T>>
void FreeManagedArray(MArray* array)
{
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -725,7 +761,7 @@ struct MConverter<SoftAssetReference<T>>
{
PLATFORM_DEBUG_BREAK; // FIXME
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -778,7 +814,7 @@ struct MConverter<Array<T>>
{
PLATFORM_DEBUG_BREAK; // FIXME
MCore::Array::Free(array);
MCore::GCHandle::Free(*(MGCHandle*)&array);
//MCore::GCHandle::Free(*(MGCHandle*)&array);
}
};
@@ -1031,6 +1067,27 @@ namespace MUtils
}
#if USE_NETCORE
/// <summary>
///
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
FORCE_INLINE String ToNativeString(const StringAnsi& str)
{
return String(str);
}
/// <summary>
///
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
FORCE_INLINE String ToNativeString(const StringAnsiView& str)
{
return String(str);
}
/// <summary>
/// Allocates new boolean array and copies data from the given unmanaged data container. The managed runtime is responsible for releasing the returned array data.
/// </summary>
@@ -1040,7 +1097,7 @@ namespace MUtils
FORCE_INLINE T* ToNativeArray(const Array<T>& data)
{
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
T* arr = (T*)MCore::GC::AllocateMemory(data.Count() * sizeof(T), true);
T* arr = (T*)MCore::GC::AllocateMemory(data.Count() * sizeof(T), false);
Platform::MemoryCopy(arr, data.Get(), data.Count() * sizeof(T));
return arr;
}
@@ -1116,7 +1173,7 @@ namespace MUtils
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
NativeArray<U> arr;
arr.length = data.Length();
arr.data = arr.length > 0 ? (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), true) : nullptr;
arr.data = arr.length > 0 ? (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), false) : nullptr;
// Convert to managed
MConverter<T, U> converter;
@@ -1136,7 +1193,7 @@ namespace MUtils
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
NativeArray<T> arr;
arr.length = data.Length();
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
// Convert to managed
MConverter<T> converter;
@@ -1188,7 +1245,7 @@ namespace MUtils
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
NativeArray<T> arr;
arr.length = data.Length();
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
// Convert to managed
MConverter<T, U> converter;
@@ -1208,7 +1265,7 @@ namespace MUtils
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
NativeArray<T> arr;
arr.length = data.Length();
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
return arr;
}
@@ -1239,7 +1296,7 @@ namespace MUtils
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
NativeArray<T> arr;
arr.length = data.Length();
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
//Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
// Convert to managed
@@ -1261,7 +1318,7 @@ namespace MUtils
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
NativeArray<T> arr;
arr.length = data.Length();
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true) : nullptr;
arr.data = arr.length > 0 ? (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), false) : nullptr;
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
return arr;
}
@@ -1302,7 +1359,7 @@ namespace MUtils
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
NativeArray<MObject*> arr;
arr.length = data.Length();
arr.data = arr.length > 0 ? (MObject**)MCore::GC::AllocateMemory(arr.length * sizeof(MObject*), true) : nullptr;
arr.data = arr.length > 0 ? (MObject**)MCore::GC::AllocateMemory(arr.length * sizeof(MObject*), false) : nullptr;
// Convert to managed
MConverter<T> converter;
@@ -1320,7 +1377,7 @@ namespace MUtils
FORCE_INLINE bool* ToBoolArray(const Array<bool>& data)
{
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true);
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), false);
memcpy(arr, data.Get(), data.Count() * sizeof(bool));
return arr;
}
@@ -1334,7 +1391,7 @@ namespace MUtils
FORCE_INLINE bool* ToBoolArray(const BitArray<AllocationType>& data)
{
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), true);
bool* arr = (bool*)MCore::GC::AllocateMemory(data.Count() * sizeof(bool), false);
for (int i = 0; i < data.Count(); i++)
arr[i] = data[i];
return arr;

View File

@@ -290,7 +290,7 @@ namespace FlaxEngine
/// </summary>
/// <param name="ptr">The pointer to the unmanaged (native) object.</param>
/// <returns>The object.</returns>
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FromUnmanagedPtr")]
public static partial Object FromUnmanagedPtr(IntPtr ptr);
/// <summary>
@@ -315,37 +315,43 @@ namespace FlaxEngine
#region Internal Calls
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create1", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create1")]
internal static partial Object Internal_Create1([MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Create2", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
internal static partial Object Internal_Create2(string typeName);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceCreated")]
internal static partial void Internal_ManagedInstanceCreated(Object managedInstance, IntPtr typeClass);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ManagedInstanceDeleted")]
internal static partial void Internal_ManagedInstanceDeleted(IntPtr nativeInstance);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Destroy", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_Destroy")]
internal static partial void Internal_Destroy(IntPtr obj, float timeLeft);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_DestroyNow", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_DestroyNow")]
internal static partial void Internal_DestroyNow(IntPtr obj);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
internal static partial string Internal_GetTypeName(IntPtr obj);
internal static string Internal_GetTypeName(IntPtr obj)
{
Internal_GetTypeName(obj, out string typeName);
return typeName;
}
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetTypeName", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
internal static partial void Internal_GetTypeName(IntPtr obj, [MarshalUsing(typeof(Interop.StringAnsiViewMarshaller))] out string typeName);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_FindObject")]
internal static partial Object Internal_FindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type, [MarshalAs(UnmanagedType.U1)] bool skipLog = false);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_TryFindObject")]
internal static partial Object Internal_TryFindObject(ref Guid id, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ChangeID", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_ChangeID")]
internal static partial void Internal_ChangeID(IntPtr obj, ref Guid id);
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetUnmanagedInterface", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(Interop.StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ObjectInternal_GetUnmanagedInterface")]
internal static partial IntPtr Internal_GetUnmanagedInterface(IntPtr obj, [MarshalUsing(typeof(Interop.SystemTypeMarshaller))] Type type);
#endregion

View File

@@ -431,6 +431,7 @@ MClass* MCore::Object::GetClass(const MObject* obj)
MString* MCore::Object::ToString(const MObject* obj)
{
CRASH;
static void* GetObjectStringPtr = GetStaticMethodPointer(TEXT("GetObjectString"));
return (MString*)CallStaticMethod<void*, const void*>(GetObjectStringPtr, obj);
}
@@ -443,28 +444,34 @@ int32 MCore::Object::GetHashCode(const MObject* obj)
MString* MCore::String::GetEmpty(const MDomain* domain)
{
CRASH;
static void* GetStringEmptyPtr = GetStaticMethodPointer(TEXT("GetStringEmpty"));
return (MString*)CallStaticMethod<void*>(GetStringEmptyPtr);
}
MString* MCore::String::New(const char* str, int32 length, const MDomain* domain)
{
CRASH;
static void* NewStringUTF8Ptr = GetStaticMethodPointer(TEXT("NewStringUTF8"));
return (MString*)CallStaticMethod<void*, const char*, int>(NewStringUTF8Ptr, str, length);
}
MString* MCore::String::New(const Char* str, int32 length, const MDomain* domain)
{
CRASH;
static void* NewStringUTF16Ptr = GetStaticMethodPointer(TEXT("NewStringUTF16"));
return (MString*)CallStaticMethod<void*, const Char*, int>(NewStringUTF16Ptr, str, length);
}
StringView MCore::String::GetChars(const MString* obj)
{
int32 length = 0;
::String& str = *(::String*)obj;
return StringView(str);
//CRASH;
/*int32 length = 0;
static void* GetStringPointerPtr = GetStaticMethodPointer(TEXT("GetStringPointer"));
const Char* chars = CallStaticMethod<const Char*, const void*, int*>(GetStringPointerPtr, obj, &length);
return StringView(chars, length);
return StringView(chars, length);*/
}
void MCore::String::Free(const MString* obj)
@@ -605,6 +612,8 @@ void MCore::GC::WriteArrayRef(MArray* dst, Span<MObject*> refs)
void* MCore::GC::AllocateMemory(int32 size, bool coTaskMem)
{
if (coTaskMem == true)
coTaskMem = coTaskMem;
static void* AllocMemoryPtr = GetStaticMethodPointer(TEXT("AllocMemory"));
return CallStaticMethod<void*, int, bool>(AllocMemoryPtr, size, coTaskMem);
}
@@ -613,6 +622,8 @@ void MCore::GC::FreeMemory(void* ptr, bool coTaskMem)
{
if (!ptr)
return;
if (coTaskMem == true)
coTaskMem = coTaskMem;
static void* FreeMemoryPtr = GetStaticMethodPointer(TEXT("FreeMemory"));
CallStaticMethod<void, void*, bool>(FreeMemoryPtr, ptr, coTaskMem);
}
@@ -1323,11 +1334,13 @@ MException::MException(MObject* exception)
MMethod* exceptionMsgGetter = exceptionMsgProp->GetGetMethod();
MString* exceptionMsg = (MString*)exceptionMsgGetter->Invoke(exception, nullptr, nullptr);
Message = MUtils::ToString(exceptionMsg);
MCore::String::Free(exceptionMsg);
MProperty* exceptionStackProp = exceptionClass->GetProperty("StackTrace");
MMethod* exceptionStackGetter = exceptionStackProp->GetGetMethod();
MString* exceptionStackTrace = (MString*)exceptionStackGetter->Invoke(exception, nullptr, nullptr);
StackTrace = MUtils::ToString(exceptionStackTrace);
MCore::String::Free(exceptionStackTrace);
MProperty* innerExceptionProp = exceptionClass->GetProperty("InnerException");
MMethod* innerExceptionGetter = innerExceptionProp->GetGetMethod();

View File

@@ -395,7 +395,7 @@ namespace FlaxEngine
/// Returns true if game scripts assembly has been loaded.
/// </summary>
/// <returns>True if game scripts assembly is loaded, otherwise false.</returns>
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_HasGameModulesLoaded", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_HasGameModulesLoaded")]
[return: MarshalAs(UnmanagedType.U1)]
public static partial bool HasGameModulesLoaded();
@@ -403,14 +403,14 @@ namespace FlaxEngine
/// Returns true if given type is from one of the game scripts assemblies.
/// </summary>
/// <returns>True if the type is from game assembly, otherwise false.</returns>
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_IsTypeFromGameScripts", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_IsTypeFromGameScripts")]
[return: MarshalAs(UnmanagedType.U1)]
public static partial bool IsTypeFromGameScripts([MarshalUsing(typeof(SystemTypeMarshaller))] Type type);
/// <summary>
/// Flushes the removed objects (disposed objects using Object.Destroy).
/// </summary>
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_FlushRemovedObjects", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ScriptingInternal_FlushRemovedObjects")]
public static partial void FlushRemovedObjects();
}
@@ -426,26 +426,26 @@ namespace FlaxEngine
/// Begins profiling a piece of code with a custom label.
/// </summary>
/// <param name="name">The name of the event.</param>
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
public static partial void BeginEvent(string name);
/// <summary>
/// Ends profiling an event.
/// </summary>
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEvent", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
public static partial void EndEvent();
/// <summary>
/// Begins GPU profiling a piece of code with a custom label.
/// </summary>
/// <param name="name">The name of the event.</param>
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_BeginEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(FlaxEngine.Interop.StringMarshaller))]
public static partial void BeginEventGPU(string name);
/// <summary>
/// Ends GPU profiling an event.
/// </summary>
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEventGPU", StringMarshalling = StringMarshalling.Custom, StringMarshallingCustomType = typeof(StringMarshaller))]
[LibraryImport("FlaxEngine", EntryPoint = "ProfilerInternal_EndEventGPU")]
public static partial void EndEventGPU();
}
}

View File

@@ -26,6 +26,15 @@
#define ScriptingObject_unmanagedPtr "__unmanagedPtr"
#define ScriptingObject_id "__internalId"
//#if USE_NETCORE
//APgI_TYPEDEF() typedef MString* ManagedString;
//APgI_TYPEDEF() typedef MString* ManagedStringView;
//APgI_TYPEDEF() typedef MString* ManagedStringAnsiView;
API_TYPEDEF() typedef String ManagedString;
API_TYPEDEF() typedef StringView ManagedStringView;
API_TYPEDEF() typedef StringAnsiView ManagedStringAnsiView;
//#endif
// TODO: don't leak memory (use some kind of late manual GC for those wrapper objects)
typedef Pair<ScriptingObject*, ScriptingTypeHandle> ScriptingObjectsInterfaceKey;
Dictionary<ScriptingObjectsInterfaceKey, void*> ScriptingObjectsInterfaceWrappers;
@@ -611,12 +620,16 @@ DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create1(MTypeObject* type)
return managedInstance;
}
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(MString* typeNameObj)
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_Create2(ManagedStringView typeNameObj)
{
// Get typename
if (typeNameObj == nullptr)
DebugLog::ThrowArgumentNull("typeName");
#if USE_NETCORE
const StringView typeNameChars = typeNameObj;
#else
const StringView typeNameChars = MCore::String::GetChars(typeNameObj);
#endif
const StringAsANSI<100> typeNameData(typeNameChars.Get(), typeNameChars.Length());
const StringAnsiView typeName(typeNameData.Get(), typeNameChars.Length());
@@ -711,10 +724,15 @@ DEFINE_INTERNAL_CALL(void) ObjectInternal_DestroyNow(ScriptingObject* obj)
obj->DeleteObjectNow();
}
DEFINE_INTERNAL_CALL(MString*) ObjectInternal_GetTypeName(ScriptingObject* obj)
DEFINE_INTERNAL_CALL(void) ObjectInternal_GetTypeName(ScriptingObject* obj, ManagedStringAnsiView* typeName)
{
#if USE_NETCORE
INTERNAL_CALL_CHECK(obj);
*typeName = obj->GetType().Fullname;
#else
INTERNAL_CALL_CHECK_RETURN(obj, nullptr);
return MUtils::ToString(obj->GetType().Fullname);
*typeName = MUtils::ToString(obj->GetType().Fullname);
#endif
}
DEFINE_INTERNAL_CALL(MObject*) ObjectInternal_FindObject(Guid* id, MTypeObject* type, bool skipLog = false)