_unbox
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:
2025-12-21 20:17:24 +02:00
parent 0973363c64
commit 3008d8037d
12 changed files with 101 additions and 29 deletions

View File

@@ -69,6 +69,7 @@ public:
{
static MObject* Box(void* value, const MClass* klass);
static void* Unbox(MObject* obj);
static void Unbox(MObject* obj, void* dest);
static MObject* New(const MClass* klass);
static void Init(MObject* obj);
static MClass* GetClass(MObject* obj);

View File

@@ -313,7 +313,10 @@ Variant MUtils::UnboxVariant(MObject* value, bool releaseHandle)
MType* mType = klass->GetType();
const MTypes mTypes = MCore::Type::GetType(mType);
void* unboxed = MCore::Object::Unbox(value);
Variant storage;
MCore::Object::Unbox(value, &storage.AsData);
void* unboxed = &storage.AsData;
// Fast type detection for in-built types
switch (mTypes)
@@ -492,13 +495,16 @@ Variant MUtils::UnboxVariant(MObject* value, bool releaseHandle)
// TODO: optimize this for large arrays to prevent multiple AllocStructure calls in Variant::SetType by using computed struct type
for (int32 i = 0; i < array.Count(); i++)
{
PLATFORM_DEBUG_BREAK; // FIXME
auto& a = array[i];
a.SetType(elementType);
void* managed = (byte*)ptr + elementSize * i;
// TODO: optimize structures unboxing to not require MObject* but raw managed value data to prevent additional boxing here
MObject* boxed = MCore::Object::New(elementClass);
Platform::MemoryCopy(MCore::Object::Unbox(boxed), managed, elementSize);
type.Struct.Unbox(a.AsBlob.Data, boxed);
//MObject* boxed = MCore::Object::New(elementClass);
//Variant storage;
MCore::Object::Unbox((MObject*)managed, &a.AsBlob.Data);
//Platform::MemoryCopy(MCore::Object::Unbox(boxed), managed, elementSize);
//type.Struct.Unbox(a.AsBlob.Data, boxed);
}
break;
}
@@ -559,7 +565,8 @@ Variant MUtils::UnboxVariant(MObject* value, bool releaseHandle)
Variant v;
v.Type = MoveTemp(VariantType(VariantType::Enum, fullname));
// TODO: what about 64-bit enum? use enum size with memcpy
v.AsUint64 = *static_cast<uint32*>(MCore::Object::Unbox(value));
PLATFORM_DEBUG_BREAK; // FIXME
MCore::Object::Unbox(value, &v.AsUint64);
if (releaseHandle)
MUtils::FreeManaged<byte>(value);
return v;
@@ -743,9 +750,10 @@ MObject* MUtils::BoxVariant(const Variant& value)
ASSERT(type.Type == ScriptingTypes::Structure);
for (int32 i = 0; i < array.Count(); i++)
{
PLATFORM_DEBUG_BREAK; // FIXME
// TODO: optimize structures boxing to not return MObject* but use raw managed object to prevent additional boxing here
MObject* boxed = type.Struct.Box(array[i].AsBlob.Data);
Platform::MemoryCopy(managedPtr + elementSize * i, MCore::Object::Unbox(boxed), elementSize);
MCore::Object::Unbox(boxed, managedPtr + elementSize * i);
}
break;
}
@@ -1176,7 +1184,9 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, MType* type, bool& failed)
auto& valueType = typeHandle.GetType();
if (valueType.ManagedClass == MCore::Type::GetClass(type))
{
return MCore::Object::Unbox(valueType.Struct.Box(value.AsBlob.Data));
PLATFORM_DEBUG_BREAK; // FIXME
MCore::Object::Unbox(valueType.Struct.Box(value.AsBlob.Data), &value.AsBlob.Data);
return &value.AsBlob.Data;
}
LOG(Error, "Cannot marshal argument of type {0} as {1}", String(valueType.Fullname), MCore::Type::ToString(type));
}
@@ -1187,9 +1197,11 @@ void* MUtils::VariantToManagedArgPtr(Variant& value, MType* type, bool& failed)
const ScriptingTypeHandle typeHandle = Scripting::FindScriptingType(fullname);
if (typeHandle)
{
PLATFORM_DEBUG_BREAK; // FIXME
auto& valueType = typeHandle.GetType();
value.SetType(VariantType(VariantType::Structure, fullname));
return MCore::Object::Unbox(valueType.Struct.Box(value.AsBlob.Data));
MCore::Object::Unbox(valueType.Struct.Box(value.AsBlob.Data), &value.AsBlob.Data);
return &value.AsBlob.Data;
}
}
}

View File

@@ -76,7 +76,7 @@ struct MConverter<bool>
void Unbox(bool& result, MObject* data)
{
if (data)
Platform::MemoryCopy(&result, MCore::Object::Unbox(data), sizeof(bool));
MCore::Object::Unbox(data, &result);
}
void FreeManaged(MObject* data)
@@ -113,7 +113,7 @@ struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class
void Unbox(T& result, MObject* data)
{
if (data)
Platform::MemoryCopy(&result, MCore::Object::Unbox(data), sizeof(T));
MCore::Object::Unbox(data, &result);
}
void ToManagedArray(MArray* result, const Span<T>& data)
@@ -678,6 +678,35 @@ namespace MUtils
return result;
}
/// <summary>
/// Unboxes MObject to the native value of the given type.
/// </summary>
///
template<>
inline bool Unbox(MObject* object)
{
MConverter<bool> converter;
int32 result;
converter.Unbox(*(bool*)&result, object);
return result != 0;
}
/// <summary>
/// Unboxes MObject to the native value of the given type.
/// </summary>
/// <param name="object">The object.</param>
/// <param name="releaseHandle">True if boxed managed handle should be released.</param>
template<>
inline bool Unbox(MObject* object, bool releaseHandle)
{
MConverter<bool> converter;
int32 result;
converter.Unbox(*(bool*)&result, object);
if (releaseHandle)
converter.FreeManaged(object);
return result != 0;
}
/// <summary>
/// Releases the managed resources of a boxed object.
/// </summary>

View File

@@ -400,9 +400,14 @@ MObject* MCore::Object::Box(void* value, const MClass* klass)
}
void* MCore::Object::Unbox(MObject* obj)
{
CRASH; // Should not be used anymore
}
void MCore::Object::Unbox(MObject* obj, void* dest)
{
static void* UnboxValuePtr = GetStaticMethodPointer(TEXT("UnboxValue"));
return CallStaticMethod<void*, void*>(UnboxValuePtr, obj);
return CallStaticMethod<void, void*, void*>(UnboxValuePtr, obj, dest);
}
MObject* MCore::Object::New(const MClass* klass)

View File

@@ -738,6 +738,11 @@ void* MCore::Object::Unbox(MObject* obj)
//return mono_object_unbox(obj);
}
void MCore::Object::Unbox(MObject* obj, void* dest)
{
CRASH; // Not applicable
}
MObject* MCore::Object::New(const MClass* klass)
{
return mono_object_new(mono_domain_get(), klass->GetNative());

View File

@@ -80,6 +80,10 @@ void* MCore::Object::Unbox(MObject* obj)
return nullptr;
}
void MCore::Object::Unbox(MObject* obj, void* dest)
{
}
MObject* MCore::Object::New(const MClass* klass)
{
return nullptr;