Add support for passing the object reference as scripting function output result
This commit is contained in:
@@ -362,6 +362,11 @@ namespace Flax.Build.Bindings
|
||||
contents.Append("out ");
|
||||
else if (parameterInfo.IsRef || UsePassByReference(buildData, parameterInfo.Type, caller))
|
||||
contents.Append("ref ");
|
||||
|
||||
// Out parameters that need additional converting will be converted at the native side (eg. object reference)
|
||||
if (parameterInfo.IsOut && !string.IsNullOrEmpty(GenerateCSharpManagedToNativeConverter(buildData, parameterInfo.Type, caller)))
|
||||
nativeType = parameterInfo.Type.Type;
|
||||
|
||||
contents.Append(nativeType);
|
||||
contents.Append(' ');
|
||||
contents.Append(parameterInfo.Name);
|
||||
@@ -399,16 +404,15 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
contents.Append("return ");
|
||||
}
|
||||
|
||||
contents.Append("Internal_").Append(functionInfo.UniqueName).Append('(');
|
||||
|
||||
// Pass parameters
|
||||
var separator = false;
|
||||
if (!functionInfo.IsStatic)
|
||||
{
|
||||
contents.Append("__unmanagedPtr");
|
||||
separator = true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < functionInfo.Parameters.Count; i++)
|
||||
{
|
||||
var parameterInfo = functionInfo.Parameters[i];
|
||||
@@ -416,29 +420,29 @@ namespace Flax.Build.Bindings
|
||||
contents.Append(", ");
|
||||
separator = true;
|
||||
|
||||
var convertFunc = GenerateCSharpManagedToNativeConverter(buildData, parameterInfo.Type, caller);
|
||||
if (string.IsNullOrWhiteSpace(convertFunc))
|
||||
{
|
||||
if (parameterInfo.IsOut)
|
||||
contents.Append("out ");
|
||||
else if (parameterInfo.IsRef || UsePassByReference(buildData, parameterInfo.Type, caller))
|
||||
contents.Append("ref ");
|
||||
if (parameterInfo.IsOut)
|
||||
contents.Append("out ");
|
||||
else if (parameterInfo.IsRef || UsePassByReference(buildData, parameterInfo.Type, caller))
|
||||
contents.Append("ref ");
|
||||
|
||||
var convertFunc = CppParamsWrappersCache[i];
|
||||
var paramName = isSetter ? "value" : parameterInfo.Name;
|
||||
if (string.IsNullOrWhiteSpace(convertFunc) || parameterInfo.IsOut)
|
||||
{
|
||||
// Pass value
|
||||
contents.Append(isSetter ? "value" : parameterInfo.Name);
|
||||
contents.Append(paramName);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parameterInfo.IsOut)
|
||||
throw new Exception($"Cannot use Out meta on parameter {parameterInfo} in function {functionInfo.Name} in {caller}.");
|
||||
if (parameterInfo.IsRef)
|
||||
throw new Exception($"Cannot use Ref meta on parameter {parameterInfo} in function {functionInfo.Name} in {caller}.");
|
||||
throw new Exception($"Cannot use Ref meta on parameter {parameterInfo} in function {functionInfo.Name} in {caller}. Use API_PARAM(Out) if you want to pass it as a result reference.");
|
||||
|
||||
// Convert value
|
||||
contents.Append(string.Format(convertFunc, isSetter ? "value" : parameterInfo.Name));
|
||||
contents.Append(string.Format(convertFunc, paramName));
|
||||
}
|
||||
}
|
||||
|
||||
// Pass additional parameters
|
||||
var customParametersCount = functionInfo.Glue.CustomParameters?.Count ?? 0;
|
||||
for (var i = 0; i < customParametersCount; i++)
|
||||
{
|
||||
@@ -448,7 +452,7 @@ namespace Flax.Build.Bindings
|
||||
separator = true;
|
||||
|
||||
var convertFunc = GenerateCSharpManagedToNativeConverter(buildData, parameterInfo.Type, caller);
|
||||
if (string.IsNullOrWhiteSpace(convertFunc))
|
||||
if (string.IsNullOrWhiteSpace(convertFunc) || parameterInfo.IsOut)
|
||||
{
|
||||
if (parameterInfo.IsOut)
|
||||
contents.Append("out ");
|
||||
@@ -466,6 +470,8 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
|
||||
contents.Append(");");
|
||||
|
||||
// Return result
|
||||
if (functionInfo.Glue.UseReferenceForResult)
|
||||
{
|
||||
contents.Append(" return resultAsRef;");
|
||||
|
||||
@@ -358,10 +358,8 @@ namespace Flax.Build.Bindings
|
||||
// Use dynamic array as wrapper container for fixed-size native arrays
|
||||
if (typeInfo.IsArray)
|
||||
{
|
||||
typeInfo.IsArray = false;
|
||||
var arrayType = new TypeInfo { Type = "Array", GenericArgs = new List<TypeInfo> { typeInfo, }, };
|
||||
var arrayType = new TypeInfo { Type = "Array", GenericArgs = new List<TypeInfo> { new TypeInfo(typeInfo) { IsArray = false } } };
|
||||
var result = GenerateCppWrapperNativeToManaged(buildData, arrayType, caller, out type, functionInfo);
|
||||
typeInfo.IsArray = true;
|
||||
return result.Replace("{0}", $"Span<{typeInfo.Type}>({{0}}, {typeInfo.ArraySize})");
|
||||
}
|
||||
|
||||
@@ -533,10 +531,8 @@ namespace Flax.Build.Bindings
|
||||
// Use dynamic array as wrapper container for fixed-size native arrays
|
||||
if (typeInfo.IsArray)
|
||||
{
|
||||
typeInfo.IsArray = false;
|
||||
var arrayType = new TypeInfo { Type = "Array", GenericArgs = new List<TypeInfo> { typeInfo, }, };
|
||||
var arrayType = new TypeInfo { Type = "Array", GenericArgs = new List<TypeInfo> { new TypeInfo(typeInfo) { IsArray = false } } };
|
||||
var result = GenerateCppWrapperManagedToNative(buildData, arrayType, caller, out type, functionInfo, out needLocalVariable);
|
||||
typeInfo.IsArray = true;
|
||||
return result + ".Get()";
|
||||
}
|
||||
|
||||
@@ -776,6 +772,12 @@ namespace Flax.Build.Bindings
|
||||
|
||||
CppParamsThatNeedConversion[i] = false;
|
||||
CppParamsWrappersCache[i] = GenerateCppWrapperManagedToNative(buildData, parameterInfo.Type, caller, out var managedType, functionInfo, out CppParamsThatNeedLocalVariable[i]);
|
||||
|
||||
// Out parameters that need additional converting will be converted at the native side (eg. object reference)
|
||||
var isOutWithManagedConverter = parameterInfo.IsOut && !string.IsNullOrEmpty(GenerateCSharpManagedToNativeConverter(buildData, parameterInfo.Type, caller));
|
||||
if (isOutWithManagedConverter)
|
||||
managedType = "MonoObject*";
|
||||
|
||||
contents.Append(managedType);
|
||||
if (parameterInfo.IsRef || parameterInfo.IsOut || UsePassByReference(buildData, parameterInfo.Type, caller))
|
||||
contents.Append('*');
|
||||
@@ -894,9 +896,11 @@ namespace Flax.Build.Bindings
|
||||
var apiType = FindApiTypeInfo(buildData, parameterInfo.Type, caller);
|
||||
if (apiType != null)
|
||||
{
|
||||
// TODO: maybe for Out-only params we could skip copying from managed data? see RayCastHit usage converted here from RayCastHitManaged
|
||||
contents.AppendFormat(" auto {0}Temp = {1};", parameterInfo.Name, param).AppendLine();
|
||||
if (parameterInfo.Type.IsPtr)
|
||||
if (parameterInfo.IsOut)
|
||||
contents.AppendFormat(" {1} {0}Temp;", parameterInfo.Name, new TypeInfo(parameterInfo.Type) { IsRef = false }.GetFullNameNative(buildData, caller)).AppendLine();
|
||||
else
|
||||
contents.AppendFormat(" auto {0}Temp = {1};", parameterInfo.Name, param).AppendLine();
|
||||
if (parameterInfo.Type.IsPtr && !parameterInfo.Type.IsRef)
|
||||
callParams += "&";
|
||||
callParams += parameterInfo.Name;
|
||||
callParams += "Temp";
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Flax.Build.Bindings
|
||||
/// <summary>
|
||||
/// The native type information for bindings generator.
|
||||
/// </summary>
|
||||
public class TypeInfo : IEquatable<TypeInfo>, IBindingsCache
|
||||
public class TypeInfo : IEquatable<TypeInfo>, IBindingsCache, ICloneable
|
||||
{
|
||||
public string Type;
|
||||
public bool IsConst;
|
||||
@@ -33,6 +33,23 @@ namespace Flax.Build.Bindings
|
||||
/// </summary>
|
||||
public bool IsConstRef => IsRef && IsConst;
|
||||
|
||||
public TypeInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public TypeInfo(TypeInfo other)
|
||||
{
|
||||
Type = other.Type;
|
||||
IsConst = other.IsConst;
|
||||
IsRef = other.IsRef;
|
||||
IsPtr = other.IsPtr;
|
||||
IsArray = other.IsArray;
|
||||
IsBitField = other.IsBitField;
|
||||
ArraySize = other.ArraySize;
|
||||
BitSize = other.BitSize;
|
||||
GenericArgs = other.GenericArgs != null ? new List<TypeInfo>(other.GenericArgs) : null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this type is POD (plain old data).
|
||||
/// </summary>
|
||||
@@ -183,5 +200,11 @@ namespace Flax.Build.Bindings
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public object Clone()
|
||||
{
|
||||
return new TypeInfo(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user