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
1362 lines
45 KiB
C++
1362 lines
45 KiB
C++
// Copyright (c) Wojciech Figat. All rights reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "MTypes.h"
|
|
#include "MClass.h"
|
|
#include "MCore.h"
|
|
#include "Engine/Core/Types/StringView.h"
|
|
#include "Engine/Core/Types/DataContainer.h"
|
|
#include "Engine/Core/Types/Variant.h"
|
|
#include "Engine/Core/Collections/Array.h"
|
|
#include "Engine/Scripting/ScriptingObject.h"
|
|
|
|
#if USE_CSHARP
|
|
|
|
/*static_assert(TIsPODType<int>::Value, "int not pod type?");
|
|
static_assert(TIsPODType<Float3>::Value, "Float3 not pod type?");
|
|
static_assert(!TIsPODType<ScriptingObject>::Value, "ScriptingObject not pod type?");
|
|
static_assert(TIsPODType<Char>::Value, "Char not pod type?");
|
|
static_assert(TIsPODType<char>::Value, "char not pod type?");*/
|
|
|
|
struct Version;
|
|
class CultureInfo;
|
|
template<typename AllocationType>
|
|
class BitArray;
|
|
|
|
namespace MUtils
|
|
{
|
|
extern FLAXENGINE_API StringView ToString(MString* str);
|
|
extern FLAXENGINE_API StringAnsi ToStringAnsi(MString* str);
|
|
extern FLAXENGINE_API void ToString(MString* str, String& result);
|
|
extern FLAXENGINE_API void ToString(MString* str, StringView& result);
|
|
extern FLAXENGINE_API void ToString(MString* str, Variant& result);
|
|
extern FLAXENGINE_API void ToString(MString* str, StringAnsi& result);
|
|
|
|
extern FLAXENGINE_API MString* ToString(const char* str);
|
|
extern FLAXENGINE_API MString* ToString(const StringAnsi& str);
|
|
extern FLAXENGINE_API MString* ToString(const String& str);
|
|
extern FLAXENGINE_API MString* ToString(const String& str, MDomain* domain);
|
|
extern FLAXENGINE_API MString* ToString(const StringAnsiView& str);
|
|
extern FLAXENGINE_API MString* ToString(const StringView& str);
|
|
extern FLAXENGINE_API MString* ToString(const StringView& str, MDomain* domain);
|
|
|
|
extern FLAXENGINE_API ScriptingTypeHandle UnboxScriptingTypeHandle(MTypeObject* value);
|
|
extern FLAXENGINE_API MTypeObject* BoxScriptingTypeHandle(const ScriptingTypeHandle& value);
|
|
extern FLAXENGINE_API VariantType UnboxVariantType(MType* type);
|
|
extern FLAXENGINE_API MTypeObject* BoxVariantType(const VariantType& value);
|
|
extern FLAXENGINE_API Variant UnboxVariant(MObject* value, bool releaseHandle = false);
|
|
extern FLAXENGINE_API MObject* BoxVariant(const Variant& value);
|
|
}
|
|
|
|
// Converter for data of type T between managed and unmanaged world
|
|
template<typename T, typename Enable = void>
|
|
struct MConverter
|
|
{
|
|
MObject* Box(const T& data, const MClass* klass);
|
|
void Unbox(T& result, MObject* data);
|
|
/*template<typename U>
|
|
void ToManaged(U& result, const T& data);
|
|
template<typename U>
|
|
void ToNative(T& result, const U& data);
|
|
void ToManaged(MObject*& result, const T& data);
|
|
void ToNative(T& result, const MObject*& data);*/
|
|
void FreeManaged(MObject* data);
|
|
void ToManagedArray(MArray* result, const Span<T>& data);
|
|
void ToNativeArray(Span<T>& result, const MArray* data);
|
|
void FreeManagedArray(MArray* array);
|
|
};
|
|
|
|
// Simple array used to pass arrays of blittable data between managed and unmanaged side.
|
|
template<typename T>
|
|
struct NativeArray
|
|
{
|
|
T* data;
|
|
int32 length;
|
|
|
|
FORCE_INLINE operator T*() const
|
|
{
|
|
return data;
|
|
}
|
|
|
|
FORCE_INLINE Span<T> ToSpan() const
|
|
{
|
|
return Span<T>(data, length);
|
|
}
|
|
};
|
|
|
|
#if USE_NETCORE
|
|
// Special case for boolean values, the handles are fixed and should not be removed
|
|
template<>
|
|
struct MConverter<bool>
|
|
{
|
|
MObject* Box(const bool& data, const MClass* klass)
|
|
{
|
|
return MCore::Object::Box((void*)&data, klass);
|
|
}
|
|
|
|
void Unbox(bool& result, MObject* data)
|
|
{
|
|
if (data)
|
|
MCore::Object::Unbox(data, &result);
|
|
}
|
|
|
|
void ToManaged(bool& result, const bool& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(bool& result, const bool& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<bool>& data)
|
|
{
|
|
Platform::MemoryCopy(MCore::Array::GetAddress(result), data.Get(), data.Length() * sizeof(bool));
|
|
}
|
|
|
|
void ToNativeArray(Span<bool>& result, const MArray* data)
|
|
{
|
|
Platform::MemoryCopy(result.Get(), MCore::Array::GetAddress(data), result.Length() * sizeof(bool));
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
#endif
|
|
|
|
// Converter for POD types (that can use raw memory copy).
|
|
template<typename T>
|
|
struct MConverter<T, typename TEnableIf<TAnd<TIsPODType<T>, TNot<TIsBaseOf<class ScriptingObject, typename TRemovePointer<T>::Type>>>::Value>::Type>
|
|
{
|
|
MObject* Box(const T& data, const MClass* klass)
|
|
{
|
|
return MCore::Object::Box((void*)&data, klass);
|
|
}
|
|
|
|
void Unbox(T& result, MObject* data)
|
|
{
|
|
if (data)
|
|
MCore::Object::Unbox(data, &result);
|
|
}
|
|
|
|
void ToManaged(T& result, const T& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(T& result, const T& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<T>& data)
|
|
{
|
|
Platform::MemoryCopy(MCore::Array::GetAddress(result), data.Get(), data.Length() * sizeof(T));
|
|
}
|
|
|
|
void ToNativeArray(Span<T>& result, const MArray* data)
|
|
{
|
|
Platform::MemoryCopy(result.Get(), MCore::Array::GetAddress(data), result.Length() * sizeof(T));
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
MCore::GCHandle::Free(*(MGCHandle*)&data);
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
// Converter for String.
|
|
template<>
|
|
struct MConverter<String>
|
|
{
|
|
MObject* Box(const String& data, const MClass* klass)
|
|
{
|
|
/*#if USE_NETCORE
|
|
MString* str = MUtils::ToString(data);
|
|
return MCore::Object::Box(str, klass);
|
|
#else*/
|
|
return (MObject*)MUtils::ToString(data);
|
|
//#endif
|
|
}
|
|
|
|
void Unbox(String& result, MObject* data)
|
|
{
|
|
/*#if USE_NETCORE
|
|
MString* str = (MString*)MCore::Object::Unbox(data);
|
|
result = MUtils::ToString(str);
|
|
#else*/
|
|
result = MUtils::ToString((MString*)data);
|
|
//#endif
|
|
}
|
|
|
|
void ToManaged(String& result, const String& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(String& result, const String& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<String>& data)
|
|
{
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = (MObject*)MUtils::ToString(data.Get()[i]);
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<String>& result, const MArray* data)
|
|
{
|
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
//MString* str = (MString*)MCore::Object::Unbox(data);
|
|
//MCore::GCHandle::Free(*(MGCHandle*)&str);
|
|
MCore::String::Free((MString*)data);
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
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);
|
|
}
|
|
};
|
|
|
|
// Converter for StringAnsi.
|
|
template<>
|
|
struct MConverter<StringAnsi>
|
|
{
|
|
MObject* Box(const StringAnsi& data, const MClass* klass)
|
|
{
|
|
return (MObject*)MUtils::ToString(data);
|
|
}
|
|
|
|
void Unbox(StringAnsi& result, MObject* data)
|
|
{
|
|
result = MUtils::ToStringAnsi((MString*)data);
|
|
}
|
|
|
|
void ToManaged(StringAnsi& result, const StringAnsi& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(StringAnsi& result, const StringAnsi& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<StringAnsi>& data)
|
|
{
|
|
if (data.Length() == 0)
|
|
return;
|
|
auto* objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = (MObject*)MUtils::ToString(data.Get()[i]);
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<StringAnsi>& result, const MArray* data)
|
|
{
|
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
MCore::String::Free((MString*)data);
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
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);
|
|
}
|
|
};
|
|
|
|
// Converter for StringView.
|
|
template<>
|
|
struct MConverter<StringView>
|
|
{
|
|
MObject* Box(const StringView& data, const MClass* klass)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
return (MObject*)MUtils::ToString(data);
|
|
}
|
|
|
|
void Unbox(StringView& result, MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = MUtils::ToString((MString*)data);
|
|
}
|
|
|
|
void ToManaged(StringView& result, const StringView& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(StringView& result, const StringView& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<StringView>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = (MObject*)MUtils::ToString(data.Get()[i]);
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<StringView>& result, const MArray* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MString** dataPtr = MCore::Array::GetAddress<MString*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
MUtils::ToString(dataPtr[i], result.Get()[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MCore::String::Free((MString*)data);
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
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);
|
|
}
|
|
};
|
|
|
|
// Converter for Variant.
|
|
template<>
|
|
struct MConverter<Variant>
|
|
{
|
|
MObject* Box(const Variant& data, const MClass* klass)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
return MUtils::BoxVariant(data);
|
|
}
|
|
|
|
void Unbox(Variant& result, MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = MUtils::UnboxVariant(data);
|
|
}
|
|
|
|
void ToManaged(Variant& result, const Variant& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(Variant& result, const Variant& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<Variant>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = MUtils::BoxVariant(data[i]);
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<Variant>& result, const MArray* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
result.Get()[i] = MUtils::UnboxVariant(dataPtr[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
// Converter for Scripting Objects (collection of pointers).
|
|
template<typename T>
|
|
struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Value>::Type>
|
|
{
|
|
MObject* Box(T* data, const MClass* klass)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
return data ? data->GetOrCreateManagedInstance() : nullptr;
|
|
}
|
|
|
|
void Unbox(T*& result, MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
}
|
|
|
|
void ToManaged(MObject*& result, const T* data)
|
|
{
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = data ? data->GetOrCreateManagedInstance() : nullptr;
|
|
}
|
|
|
|
void ToNative(T*& result, const MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<T*>& data)
|
|
{
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = data.Get()[i] ? data.Get()[i]->GetOrCreateManagedInstance() : nullptr;
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<T*>& result, const MArray* data)
|
|
{
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
// Converter for Scripting Objects (collection of values).
|
|
template<typename T>
|
|
struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Value>::Type>
|
|
{
|
|
MObject* Box(const T& data, const MClass* klass)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
return data.GetOrCreateManagedInstance();
|
|
}
|
|
|
|
void ToManaged(MObject*& result, const T& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(T& result, const MObject*& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
/*void ToManaged(MObject*& result, const T*& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(T*& result, const MObject*& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}*/
|
|
|
|
void ToManagedArray(MArray* result, const Span<T>& data)
|
|
{
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = data.Get()[i].GetOrCreateManagedInstance();
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
// Converter for ScriptingObject References.
|
|
template<typename T>
|
|
class ScriptingObjectReference;
|
|
|
|
template<typename T>
|
|
struct MConverter<ScriptingObjectReference<T>>
|
|
{
|
|
MObject* Box(const ScriptingObjectReference<T>& data, const MClass* klass)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
return data.GetManagedInstance();
|
|
}
|
|
|
|
void Unbox(ScriptingObjectReference<T>& result, MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
}
|
|
|
|
void ToManaged(MObject*& result, const ScriptingObjectReference<T>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(ScriptingObjectReference<T>& result, const MObject*& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<ScriptingObjectReference<T>>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = data[i].GetManagedInstance();
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<ScriptingObjectReference<T>>& result, const MArray* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
// Converter for Asset References.
|
|
template<typename T>
|
|
class AssetReference;
|
|
|
|
template<typename T>
|
|
struct MConverter<AssetReference<T>>
|
|
{
|
|
MObject* Box(const AssetReference<T>& data, const MClass* klass)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
return data.GetManagedInstance();
|
|
}
|
|
|
|
void Unbox(AssetReference<T>& result, MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
}
|
|
|
|
void ToManaged(MObject*& result, const AssetReference<T>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
result = data.GetManagedInstance();
|
|
}
|
|
|
|
void ToNative(AssetReference<T>& result, const MObject* data)
|
|
{
|
|
result = (T*)ScriptingObject::ToNative(data);
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<AssetReference<T>>& data)
|
|
{
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = data[i].GetManagedInstance();
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<AssetReference<T>>& result, const MArray* data)
|
|
{
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
// TODO: use MarshalAs=Guid on SoftAssetReference to pass guid over bindings and not load asset in glue code
|
|
template<typename T>
|
|
class SoftAssetReference;
|
|
template<typename T>
|
|
struct MConverter<SoftAssetReference<T>>
|
|
{
|
|
|
|
template <typename U>
|
|
void ToManaged(U& result, const SoftAssetReference<T>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
template <typename U>
|
|
void ToNative(SoftAssetReference<T>& result, const U& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManaged(MObject*& result, const SoftAssetReference<T>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(SoftAssetReference<T>& result, const MObject*& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToManagedArray(MArray* result, const Span<SoftAssetReference<T>>& data)
|
|
{
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
if (data.Length() == 0)
|
|
return;
|
|
MObject** objects = (MObject**)Allocator::Allocate(data.Length() * sizeof(MObject*));
|
|
for (int32 i = 0; i < data.Length(); i++)
|
|
objects[i] = data[i].GetManagedInstance();
|
|
MCore::GC::WriteArrayRef(result, Span<MObject*>(objects, data.Length()));
|
|
Allocator::Free(objects);
|
|
}
|
|
|
|
void ToNativeArray(Span<SoftAssetReference<T>>& result, const MArray* data)
|
|
{
|
|
//PLATFORM_DEBUG_BREAK; // FIXME
|
|
MObject** dataPtr = MCore::Array::GetAddress<MObject*>(data);
|
|
for (int32 i = 0; i < result.Length(); i++)
|
|
result.Get()[i] = (T*)ScriptingObject::ToNative(dataPtr[i]);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
// Converter for Array.
|
|
template<typename T>
|
|
struct MConverter<Array<T>>
|
|
{
|
|
void ToManaged(Array<T>& result, const Array<T>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
void ToNative(Array<T>& result, const Array<T>& data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
}
|
|
|
|
MObject* Box(const Array<T>& data, const MClass* klass)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
if (!klass)
|
|
return nullptr;
|
|
MArray* result = MCore::Array::New(klass->GetElementClass(), data.Count());
|
|
MConverter<T> converter;
|
|
converter.ToManagedArray(result, Span<T>(data.Get(), data.Count()));
|
|
return (MObject*)result;
|
|
}
|
|
|
|
void Unbox(Array<T>& result, MObject* data)
|
|
{
|
|
MArray* array = MCore::Array::Unbox(data);
|
|
const int32 length = array ? MCore::Array::GetLength(array) : 0;
|
|
result.Resize(length);
|
|
MConverter<T> converter;
|
|
Span<T> resultSpan(result.Get(), length);
|
|
converter.ToNativeArray(resultSpan, array);
|
|
}
|
|
|
|
void FreeManaged(MObject* data)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MArray* array = (MArray*)data;
|
|
MConverter<T> converter;
|
|
converter.FreeManagedArray(array);
|
|
//MCore::Array::Free(array);
|
|
//MCore::GCHandle::Free(*(MGCHandle*)&data);
|
|
}
|
|
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
PLATFORM_DEBUG_BREAK; // FIXME
|
|
MCore::Array::Free(array);
|
|
MCore::GCHandle::Free(*(MGCHandle*)&array);
|
|
}
|
|
};
|
|
|
|
namespace MUtils
|
|
{
|
|
// Outputs the full typename for the type of the specified object.
|
|
extern FLAXENGINE_API StringAnsiView GetClassFullname(MObject* obj);
|
|
|
|
// Returns the class of the provided object.
|
|
extern FLAXENGINE_API MClass* GetClass(MObject* object);
|
|
|
|
// Returns the class of the provided type.
|
|
extern FLAXENGINE_API MClass* GetClass(MTypeObject* type);
|
|
|
|
// Returns the class of the provided VariantType value.
|
|
extern FLAXENGINE_API MClass* GetClass(const VariantType& value);
|
|
|
|
// Returns the class of the provided Variant value.
|
|
extern FLAXENGINE_API MClass* GetClass(const Variant& value);
|
|
|
|
// Returns the type of the provided object.
|
|
extern FLAXENGINE_API MTypeObject* GetType(MObject* object);
|
|
|
|
// Returns the type of the provided class.
|
|
extern FLAXENGINE_API MTypeObject* GetType(MClass* klass);
|
|
|
|
/// <summary>
|
|
/// Boxes the native value into the managed object.
|
|
/// </summary>
|
|
/// <param name="value">The value.</param>
|
|
/// <param name="valueClass">The value type class.</param>
|
|
template<class T>
|
|
MObject* Box(const T& value, const MClass* valueClass)
|
|
{
|
|
MConverter<T> converter;
|
|
return converter.Box(value, valueClass);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Unboxes MObject to the native value of the given type.
|
|
/// </summary>
|
|
///
|
|
template<class T>
|
|
T Unbox(MObject* object)
|
|
{
|
|
MConverter<T> converter;
|
|
T result;
|
|
converter.Unbox(result, object);
|
|
return result;
|
|
}
|
|
|
|
/// <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<class T>
|
|
T Unbox(MObject* object, bool releaseHandle)
|
|
{
|
|
MConverter<T> converter;
|
|
T result;
|
|
converter.Unbox(result, object);
|
|
if (releaseHandle)
|
|
converter.FreeManaged(object);
|
|
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>
|
|
template<class T>
|
|
void FreeManaged(MObject* object)
|
|
{
|
|
MConverter<T> converter;
|
|
converter.FreeManaged(object);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Releases the managed resources of a boxed object.
|
|
/// </summary>
|
|
template<class T>
|
|
void FreeManagedArray(MArray* array)
|
|
{
|
|
MConverter<T> converter;
|
|
converter.FreeManagedArray(array);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Links managed array data to the unmanaged BytesContainer.
|
|
/// </summary>
|
|
/// <param name="arrayObj">The array object.</param>
|
|
/// <returns>The result data container with linked array data bytes (not copied).</returns>
|
|
extern FLAXENGINE_API BytesContainer LinkArray(MArray* arrayObj);
|
|
|
|
/// <summary>
|
|
/// Allocates new managed array of data and copies contents from given native array.
|
|
/// </summary>
|
|
/// <param name="data">The array object.</param>
|
|
/// <param name="valueClass">The array values type class.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T>
|
|
MArray* ToArray(const Span<T>& data, const MClass* valueClass)
|
|
{
|
|
if (!valueClass)
|
|
return nullptr;
|
|
MArray* result = MCore::Array::New(valueClass, data.Length());
|
|
MConverter<T> converter;
|
|
converter.ToManagedArray(result, data);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allocates new managed array of data and copies contents from given native array.
|
|
/// </summary>
|
|
/// <param name="data">The array object.</param>
|
|
/// <param name="valueClass">The array values type class.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T, typename AllocationType>
|
|
FORCE_INLINE MArray* ToArray(const Array<T, AllocationType>& data, const MClass* valueClass)
|
|
{
|
|
return MUtils::ToArray(Span<T>(data.Get(), data.Count()), valueClass);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts the managed array into native array container object.
|
|
/// </summary>
|
|
/// <param name="arrayObj">The managed array object.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T, typename AllocationType = HeapAllocation>
|
|
Array<T, AllocationType> ToArray(MArray* arrayObj)
|
|
{
|
|
Array<T, AllocationType> result;
|
|
const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0;
|
|
result.Resize(length);
|
|
MConverter<T> converter;
|
|
Span<T> resultSpan(result.Get(), length);
|
|
converter.ToNativeArray(resultSpan, arrayObj);
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts the managed array into native Span.
|
|
/// </summary>
|
|
/// <param name="arrayObj">The managed array object.</param>
|
|
/// <returns>The output array pointer and size.</returns>
|
|
template<typename T>
|
|
Span<T> ToSpan(MArray* arrayObj)
|
|
{
|
|
T* ptr = (T*)MCore::Array::GetAddress(arrayObj);
|
|
const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0;
|
|
return Span<T>(ptr, length);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts the native array into native Span.
|
|
/// </summary>
|
|
/// <param name="data">The native array object.</param>
|
|
/// <returns>The output array pointer and size.</returns>
|
|
template<typename T, typename AllocationType = HeapAllocation>
|
|
FORCE_INLINE Span<T> ToSpan(const Array<T, AllocationType>& data)
|
|
{
|
|
return Span<T>(data.Get(), data.Count());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Links managed array data to the unmanaged DataContainer (must use simple type like struct or float/int/bool).
|
|
/// </summary>
|
|
/// <param name="arrayObj">The array object.</param>
|
|
/// <param name="result">The result data (linked not copied).</param>
|
|
template<typename T>
|
|
void ToArray(MArray* arrayObj, DataContainer<T>& result)
|
|
{
|
|
const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0;
|
|
if (length == 0)
|
|
{
|
|
result.Release();
|
|
return;
|
|
}
|
|
T* bytesRaw = (T*)MCore::Array::GetAddress(arrayObj);
|
|
result.Link(bytesRaw, length);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allocates new managed bytes array and copies data from the given unmanaged data container.
|
|
/// </summary>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
FORCE_INLINE MArray* ToArray(const Span<byte>& data)
|
|
{
|
|
return ToArray(data, MCore::TypeCache::Byte);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allocates new managed bytes array and copies data from the given unmanaged data container.
|
|
/// </summary>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
FORCE_INLINE MArray* ToArray(Array<byte>& data)
|
|
{
|
|
return ToArray(Span<byte>(data.Get(), data.Count()), MCore::TypeCache::Byte);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allocates new managed strings array and copies data from the given unmanaged data container.
|
|
/// </summary>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
FORCE_INLINE MArray* ToArray(const Span<String>& data)
|
|
{
|
|
return ToArray(data, MCore::TypeCache::String);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allocates new managed strings array and copies data from the given unmanaged data container.
|
|
/// </summary>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
FORCE_INLINE MArray* ToArray(const Array<String>& data)
|
|
{
|
|
return ToArray(Span<String>(data.Get(), data.Count()), MCore::TypeCache::String);
|
|
}
|
|
|
|
#if USE_NETCORE
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T>
|
|
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);
|
|
Platform::MemoryCopy(arr, data.Get(), data.Count() * sizeof(T));
|
|
return arr;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Allocates new managed array of data and copies contents from given native array.
|
|
/// </summary>
|
|
/// <param name="data">The array object.</param>
|
|
/// <param name="valueClass">The array values type class.</param>
|
|
/// <returns>The output array.</returns>
|
|
/*template<typename T, typename U>
|
|
NativeArray<U> ToManagedArrayWrapper(const Span<T>& data, const MClass* valueClass)
|
|
{
|
|
if (!valueClass)
|
|
return nullptr;
|
|
MArray* result = MCore::Array::New(valueClass, data.Length());
|
|
MConverter<T> converter;
|
|
converter.ToManagedArray(result, data);
|
|
return result;
|
|
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
NativeArray<U> arr;
|
|
arr.length = data.Count();
|
|
arr.data = (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), true);
|
|
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(U));
|
|
return arr;
|
|
}*/
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
/*template<typename T, typename AllocationType = HeapAllocation>
|
|
FORCE_INLINE NativeArray<T> ToNativeArrayWrapper(const Array<T, AllocationType>& data)
|
|
{
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
NativeArray<T> arr;
|
|
arr.length = data.Count();
|
|
arr.data = (T*)MCore::GC::AllocateMemory(arr.length * sizeof(T), true);
|
|
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T, typename U, typename AllocationType = HeapAllocation>
|
|
FORCE_INLINE NativeArray<U> ToNativeArrayWrapper(const Array<T, AllocationType>& data)
|
|
{
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
NativeArray<U> arr;
|
|
arr.length = data.Count();
|
|
arr.data = (U*)MCore::GC::AllocateMemory(arr.length * sizeof(U), true);
|
|
|
|
// Convert to managed
|
|
MConverter<T, U> converter;
|
|
for (int i = 0; i < arr.length; ++i)
|
|
arr.data[i] = converter.ToManaged(data[i]);
|
|
return arr;
|
|
}*/
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T, typename U>
|
|
FORCE_INLINE NativeArray<U> ToManagedArrayWrapperConvert(const Span<T>& data)
|
|
{
|
|
// 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;
|
|
|
|
// Convert to managed
|
|
MConverter<T, U> converter;
|
|
for (int i = 0; i < arr.length; ++i)
|
|
converter.ToManaged(arr.data[i], data[i]);
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T>
|
|
FORCE_INLINE NativeArray<T> ToNativeArrayWrapperConvertGeneric(const Span<MObject*>& data)
|
|
{
|
|
// 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;
|
|
|
|
// Convert to managed
|
|
MConverter<T> converter;
|
|
for (int i = 0; i < arr.length; ++i)
|
|
{
|
|
converter.ToNative(arr.data[i], data[i]);
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T, typename AllocationType = HeapAllocation>
|
|
FORCE_INLINE void ToNativeArrayWrapperConvertGeneric(const Span<MObject*>& data, Array<T, AllocationType>& array)
|
|
{
|
|
if (!array.IsEmpty())
|
|
PLATFORM_DEBUG_BREAK; // TODO: does the array require ClearDelete instead?
|
|
|
|
auto length = data.Length();
|
|
array.Resize(length, false);
|
|
//array.Clear();
|
|
//array.EnsureCapacity(length);
|
|
|
|
MConverter<T> converter;
|
|
for (int i = 0; i < length; ++i)
|
|
{
|
|
// Make sure the destination is default initialized first
|
|
//array.AddUninitialized();
|
|
//array.AddDefault();
|
|
//T& dest = array.Get()[i];
|
|
//new(&dest)AssetReference<T>();
|
|
|
|
// Convert from managed
|
|
converter.ToNative(array.Get()[i], data[i]);
|
|
}
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T, typename U>
|
|
FORCE_INLINE NativeArray<T> ToNativeArrayWrapperConvert(const Span<U>& data)
|
|
{
|
|
// 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;
|
|
|
|
// Convert to managed
|
|
MConverter<T, U> converter;
|
|
for (int i = 0; i < arr.length; ++i)
|
|
converter.ToNative(arr.data[i], data[i]);
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T>
|
|
FORCE_INLINE NativeArray<T> ToNativeArrayWrapperCopy(const Span<T>& data)
|
|
{
|
|
// 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;
|
|
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
/*FORCE_INLINE NativeArray<Char> ToManagedArrayWrapper(const Span<Char>& data)
|
|
{
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
NativeArray<Char> arr;
|
|
arr.length = data.Length();
|
|
arr.data = (Char*)MCore::GC::AllocateMemory(arr.length * sizeof(Char), true);
|
|
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(Char));
|
|
return arr;
|
|
}*/
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T>
|
|
FORCE_INLINE NativeArray<T> ToManagedArrayWrapperConvert(const Span<T>& data)
|
|
{
|
|
// 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;
|
|
//Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
|
|
|
// Convert to managed
|
|
MConverter<T> converter;
|
|
for (int i = 0; i < arr.length; ++i)
|
|
converter.ToManaged(arr.data[i], data[i]);
|
|
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename T>
|
|
FORCE_INLINE NativeArray<T> ToManagedArrayWrapperCopy(const Span<T>& data)
|
|
{
|
|
// 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;
|
|
Platform::MemoryCopy(arr.data, data.Get(), arr.length * sizeof(T));
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
/*template<typename T>
|
|
FORCE_INLINE NativeArray<MObject*> ToManagedArrayWrapperPointer(const Span<T*>& data)
|
|
{
|
|
// System.Runtime.InteropServices.Marshalling.ArrayMarshaller uses CoTask memory alloc to native data pointer
|
|
NativeArray<MObject*> arr;
|
|
arr.length = data.Length();
|
|
arr.data = (MObject**)MCore::GC::AllocateMemory(arr.length * sizeof(MObject*), true);
|
|
|
|
// Convert to managed
|
|
MConverter<T*> converter;
|
|
for (int i = 0; i < arr.length; ++i)
|
|
{
|
|
MObject*& ptr = arr.data[i];
|
|
const T& asd = data[i];
|
|
converter.ToManaged(ptr, asd);
|
|
}
|
|
|
|
return arr;
|
|
}*/
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<class T>
|
|
FORCE_INLINE NativeArray<MObject*> ToManagedArrayWrapperPointer(const Span<T>& data)
|
|
{
|
|
// 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;
|
|
|
|
// Convert to managed
|
|
MConverter<T> converter;
|
|
for (int i = 0; i < arr.length; ++i)
|
|
converter.ToManaged(arr.data[i], data[i]);
|
|
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
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);
|
|
memcpy(arr, data.Get(), data.Count() * sizeof(bool));
|
|
return arr;
|
|
}
|
|
|
|
/// <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>
|
|
/// <param name="data">The input data.</param>
|
|
/// <returns>The output array.</returns>
|
|
template<typename AllocationType = HeapAllocation>
|
|
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);
|
|
for (int i = 0; i < data.Count(); i++)
|
|
arr[i] = data[i];
|
|
return arr;
|
|
}
|
|
#else
|
|
FORCE_INLINE bool* ToBoolArray(const Array<bool>& data)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
template<typename AllocationType = HeapAllocation>
|
|
FORCE_INLINE bool* ToBoolArray(const BitArray<AllocationType>& data)
|
|
{
|
|
return nullptr;
|
|
}
|
|
#endif
|
|
|
|
extern void* VariantToManagedArgPtr(Variant& value, MType* type, bool& failed);
|
|
|
|
extern MObject* ToManaged(const Version& value);
|
|
extern Version ToNative(MObject* value);
|
|
};
|
|
|
|
#endif
|