_wip temporary array thingy

This commit is contained in:
2025-04-28 21:05:34 +03:00
parent 180e17fa23
commit 00fbb73825
2 changed files with 194 additions and 9 deletions

View File

@@ -399,6 +399,72 @@ struct MConverter<Array<T>>
namespace MUtils
{
template<typename T, typename AllocationType>
Array<T, AllocationType>* GetTemporaryArray();
template<typename T, typename AllocationType>
void ReleaseTemporaryArray(Array<T, AllocationType>* array);
template<typename T, typename AllocationType>
class TemporaryArray
{
public:
Array<T, AllocationType>* _array = nullptr;
TemporaryArray()
{
_array = GetTemporaryArray<T, AllocationType>();
}
TemporaryArray(TemporaryArray&& other)
{
_array = other._array;
other._array = nullptr;
}
~TemporaryArray()
{
if (_array != nullptr)
{
ReleaseTemporaryArray<T, AllocationType>(_array);
_array = nullptr;
}
}
TemporaryArray& operator=(const TemporaryArray&& other)
{
if (this != &other)
*this = MoveTemp(other);
return *this;
}
TemporaryArray& operator=(TemporaryArray&& other)
{
if (this != &other)
*this = MoveTemp(other);
return *this;
}
FORCE_INLINE int32 Count() const
{
return _array->Count();
}
FORCE_INLINE void Resize(const int32 size, const bool preserveContents = true)
{
_array->Count();
}
operator Array<T, AllocationType>& () { return *_array; };
//operator Array<T, AllocationType>() const { return *_array; };
//operator const Array<T, AllocationType>&() const { return *_array; };
//operator const Array<T, AllocationType>&() const { return _array; };
};
// Outputs the full typename for the type of the specified object.
extern FLAXENGINE_API const StringAnsi& GetClassFullname(MObject* obj);
@@ -468,6 +534,17 @@ namespace MUtils
return result;
}
template<typename T>
MArray* ToArray(MArray** result, const Span<T>& data, const MClass* valueClass)
{
if (!valueClass)
return nullptr;
*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>
@@ -480,6 +557,18 @@ namespace MUtils
return MUtils::ToArray(Span<T>(data.Get(), data.Count()), valueClass);
}
template<typename T, typename AllocationType>
FORCE_INLINE MArray* ToArray(MArray** result, const TemporaryArray<T, AllocationType>& data, const MClass* valueClass)
{
return MUtils::ToArray(result, Span<T>(data._array->Get(), data._array->Count()), valueClass);
}
template<typename T, typename AllocationType>
FORCE_INLINE MArray* ToArray(MArray** result, const Array<T, AllocationType>& data, const MClass* valueClass)
{
return MUtils::ToArray(result, Span<T>(data.Get(), data.Count()), valueClass);
}
/// <summary>
/// Converts the managed array into native array container object.
/// </summary>
@@ -497,6 +586,23 @@ namespace MUtils
return result;
}
/// <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(Array<T, AllocationType>& result, MArray* arrayObj)
{
const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0;
result.Clear();
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>
@@ -549,6 +655,11 @@ namespace MUtils
return ToArray(data, MCore::TypeCache::Byte);
}
FORCE_INLINE MArray* ToArray(MArray** result, const Span<byte>& data)
{
return ToArray(result, data, MCore::TypeCache::Byte);
}
/// <summary>
/// Allocates new managed bytes array and copies data from the given unmanaged data container.
/// </summary>
@@ -559,6 +670,11 @@ namespace MUtils
return ToArray(Span<byte>(data.Get(), data.Count()), MCore::TypeCache::Byte);
}
FORCE_INLINE MArray* ToArray(MArray** result, Array<byte>& data)
{
return ToArray(result, 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>
@@ -569,6 +685,11 @@ namespace MUtils
return ToArray(data, MCore::TypeCache::String);
}
FORCE_INLINE MArray* ToArray(MArray** result, const Span<String>& data)
{
return ToArray(result, data, MCore::TypeCache::String);
}
/// <summary>
/// Allocates new managed strings array and copies data from the given unmanaged data container.
/// </summary>
@@ -579,6 +700,57 @@ namespace MUtils
return ToArray(Span<String>(data.Get(), data.Count()), MCore::TypeCache::String);
}
FORCE_INLINE MArray* ToArray(MArray** result, const Array<String>& data)
{
return ToArray(result, Span<String>(data.Get(), data.Count()), MCore::TypeCache::String);
}
/// <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>
TemporaryArray<T, AllocationType> ToArrayTemporary(MArray* arrayObj)
{
TemporaryArray<T, AllocationType> result;
const int32 length = arrayObj ? MCore::Array::GetLength(arrayObj) : 0;
result._array->Resize(length, false);
MConverter<T> converter;
Span<T> resultSpan(result._array->Get(), length);
converter.ToNativeArray(resultSpan, arrayObj);
return result;
}
template<typename T, typename AllocationType = HeapAllocation>
Array<T, AllocationType>* ManageTemporaryArray(Array<T, AllocationType>* array)
{
static Array<T, AllocationType> result; // TODO: Array of arrays
if (array == nullptr)
{
// Rent array
return &result;
}
else
{
// Release
return nullptr;
}
}
template<typename T, typename AllocationType = HeapAllocation>
Array<T, AllocationType>* GetTemporaryArray()
{
return ManageTemporaryArray<T, AllocationType>(nullptr);
}
template<typename T, typename AllocationType = HeapAllocation>
void ReleaseTemporaryArray(Array<T, AllocationType>* array)
{
ManageTemporaryArray<T, AllocationType>(array);
}
#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.

View File

@@ -558,9 +558,9 @@ namespace Flax.Build.Bindings
var genericArgs = arrayApiType.MarshalAs.GetFullNameNative(buildData, caller);
if (typeInfo.GenericArgs.Count != 1)
genericArgs += ", " + typeInfo.GenericArgs[1];
return "MUtils::ToArray(Array<" + genericArgs + ">({0}), " + GenerateCppGetMClass(buildData, arrayTypeInfo, caller, functionInfo) + ")";
return "MUtils::ToArray({1}, Array<" + genericArgs + ">({0}), " + GenerateCppGetMClass(buildData, arrayTypeInfo, caller, functionInfo) + ")";
}
return "MUtils::ToArray({0}, " + GenerateCppGetMClass(buildData, arrayTypeInfo, caller, functionInfo) + ")";
return "MUtils::ToArray({1}, {0}, " + GenerateCppGetMClass(buildData, arrayTypeInfo, caller, functionInfo) + ")"; //
}
// Span
@@ -760,15 +760,23 @@ namespace Flax.Build.Bindings
genericArgs += ", " + typeInfo.GenericArgs[1];
type = "MArray*";
var result = "MUtils::ToArray<" + genericArgs + ">({0})";
string result;
bool useTemporaryArrays = ((typeInfo.IsRef && typeInfo.IsConst));
if (/*functionInfo != null ||*/ CppNonPodTypesConvertingGeneration)
result = "MUtils::ToArray<" + genericArgs + ">({0})";
else if (true || useTemporaryArrays)
result = "MUtils::ToArrayTemporary<" + genericArgs + ">({0})";
else
result = "MUtils::ToArray<" + genericArgs + ">({1}, {0})";
if (arrayApiType != null && arrayApiType.MarshalAs != null)
{
string previousType = $"Array<{genericArgs}>";
// Convert array that uses different type for marshalling
genericArgs = typeInfo.GenericArgs[0].GetFullNameNative(buildData, caller);
if (typeInfo.GenericArgs.Count != 1)
genericArgs += ", " + typeInfo.GenericArgs[1];
result = $"Array<{genericArgs}>({result})";
result = $"Array<{genericArgs}>(({previousType}){result})";
}
return result;
}
@@ -1085,6 +1093,8 @@ namespace Flax.Build.Bindings
}
var useInlinedReturn = true;
if (returnValueType.StartsWith("MArray*") /*&& (functionInfo.ReturnType.IsArray || functionInfo.ReturnType.Type == "Array")*/)
useInlinedReturn = false;
for (var i = 0; i < functionInfo.Parameters.Count; i++)
{
var parameterInfo = functionInfo.Parameters[i];
@@ -1206,7 +1216,7 @@ namespace Flax.Build.Bindings
if (useInlinedReturn)
callBegin += "return ";
else
callBegin += "auto __result = ";
callBegin += returnValueType + " __result; __result = ";
}
#if USE_NETCORE
@@ -1258,7 +1268,7 @@ namespace Flax.Build.Bindings
else
{
// Convert value
param += string.Format(CppParamsWrappersCache[i], name);
param += string.Format(CppParamsWrappersCache[i], name, parameterInfo.Name);
}
// Special case for output result parameters that needs additional converting from native to managed format (such as non-POD structures or output array parameter)
@@ -1322,7 +1332,7 @@ namespace Flax.Build.Bindings
}
if (!string.IsNullOrEmpty(returnValueConvert))
{
contents.AppendFormat(returnValueConvert, call);
contents.AppendFormat(returnValueConvert, call, "&__result");
}
else
{
@@ -1342,7 +1352,8 @@ namespace Flax.Build.Bindings
// Special case for output result parameters that needs additional converting from native to managed format (such as non-POD structures or output array parameter)
if (CppParamsThatNeedConversion[i])
{
var value = string.Format(CppParamsThatNeedConversionWrappers[i], parameterInfo.Name + "Temp");
var parmName = parameterInfo.IsRef || parameterInfo.Type.IsRef ? parameterInfo.Name : "&" + parameterInfo.Name;
var value = string.Format(CppParamsThatNeedConversionWrappers[i], parameterInfo.Name + "Temp", parmName);
// MObject* parameters returned by reference need write barrier for GC
if (parameterInfo.IsOut)
@@ -3048,9 +3059,11 @@ namespace Flax.Build.Bindings
var wrapper = CppParamsWrappersCache[i];
header.AppendFormat(" result.{0} = ", fieldInfo.Name);
if (string.IsNullOrEmpty(wrapper))
{
header.Append("value." + fieldInfo.Name);
}
else
header.AppendFormat(wrapper, "value." + fieldInfo.Name);
header.AppendFormat(wrapper, "value." + fieldInfo.Name, "&result." + fieldInfo.Name);
header.Append(';').AppendLine();
}
header.Append(" return result;").AppendLine();