diff --git a/Source/Engine/Animations/AnimationGraph.cs b/Source/Engine/Animations/AnimationGraph.cs
index 995b42662..3dae30b81 100644
--- a/Source/Engine/Animations/AnimationGraph.cs
+++ b/Source/Engine/Animations/AnimationGraph.cs
@@ -3,6 +3,7 @@
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.Marshalling;
+using FlaxEngine.Interop;
namespace FlaxEngine
{
diff --git a/Source/Engine/Engine/NativeInterop.cs b/Source/Engine/Engine/NativeInterop.cs
index 9e871e2fb..68208d7fe 100644
--- a/Source/Engine/Engine/NativeInterop.cs
+++ b/Source/Engine/Engine/NativeInterop.cs
@@ -388,7 +388,7 @@ namespace FlaxEngine.Interop
className = className.Substring(parentClassName.Length);
}
string marshallerName = className + "Marshaller";
- string internalAssemblyQualifiedName = $"{@namespace}.{parentClassName}{marshallerName}+{className}Internal,{String.Join(',', splits.Skip(1))}";
+ string internalAssemblyQualifiedName = $"{@namespace}.Interop.{parentClassName}{marshallerName}+{className}Internal,{String.Join(',', splits.Skip(1))}";
return FindType(internalAssemblyQualifiedName);
}
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
index beb3ebdd3..1e50ba4e3 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
@@ -574,8 +574,13 @@ namespace Flax.Build.Bindings
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.ManagedHandleMarshaller))";
else if (FindApiTypeInfo(buildData, functionInfo.ReturnType, caller)?.IsInterface ?? false)
{
+ var apiType = FindApiTypeInfo(buildData, functionInfo.ReturnType, caller);
+ var fullReturnValueType = returnValueType;
+ if (!string.IsNullOrEmpty(apiType?.Namespace))
+ fullReturnValueType = $"{apiType.Namespace}.Interop.{returnValueType}";
+
// Interfaces are not supported by NativeMarshallingAttribute, marshal the parameter
- returnMarshalType = $"MarshalUsing(typeof({returnValueType}Marshaller))";
+ returnMarshalType = $"MarshalUsing(typeof({fullReturnValueType}Marshaller))";
}
else if (functionInfo.ReturnType.Type == "MonoArray" || functionInfo.ReturnType.Type == "MArray")
returnMarshalType = "MarshalUsing(typeof(FlaxEngine.Interop.SystemArrayMarshaller))";
@@ -933,10 +938,11 @@ namespace Flax.Build.Bindings
contents.AppendLine();
// Namespace begin
+ string interopNamespace = "";
if (!string.IsNullOrEmpty(classInfo.Namespace))
{
- contents.AppendFormat("namespace ");
- contents.AppendLine(classInfo.Namespace);
+ interopNamespace = $"{classInfo.Namespace}.Interop";
+ contents.AppendLine($"namespace {classInfo.Namespace}");
contents.AppendLine("{");
indent += " ";
}
@@ -948,10 +954,12 @@ namespace Flax.Build.Bindings
GenerateCSharpAttributes(buildData, contents, indent, classInfo, useUnmanaged);
#if USE_NETCORE
string marshallerName = "";
+ string marshallerFullName = "";
if (!classInfo.IsStatic)
{
marshallerName = classInfo.Name + "Marshaller";
- contents.Append(indent).AppendLine($"[NativeMarshalling(typeof({marshallerName}))]");
+ marshallerFullName = !string.IsNullOrEmpty(interopNamespace) ? $"{interopNamespace}.{marshallerName}" : marshallerName;
+ contents.Append(indent).AppendLine($"[NativeMarshalling(typeof({marshallerFullName}))]");
}
#endif
contents.Append(indent).Append(GenerateCSharpAccessLevel(classInfo.Access));
@@ -1376,6 +1384,13 @@ namespace Flax.Build.Bindings
#if USE_NETCORE
if (!string.IsNullOrEmpty(marshallerName))
{
+ if (!string.IsNullOrEmpty(interopNamespace))
+ {
+ contents.AppendLine("}");
+ contents.AppendLine($"namespace {interopNamespace}");
+ contents.AppendLine("{");
+ }
+
contents.AppendLine();
contents.AppendLine(string.Join("\n" + indent, (indent + $$"""
///
@@ -1384,15 +1399,15 @@ namespace Flax.Build.Bindings
#if FLAX_EDITOR
[HideInEditor]
#endif
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedIn, typeof({{marshallerName}}.ManagedToNative))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedOut, typeof({{marshallerName}}.ManagedToNative))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementIn, typeof({{marshallerName}}.ManagedToNative))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedOut, typeof({{marshallerName}}.NativeToManaged))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedIn, typeof({{marshallerName}}.NativeToManaged))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementOut, typeof({{marshallerName}}.NativeToManaged))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedRef, typeof({{marshallerName}}.Bidirectional))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedRef, typeof({{marshallerName}}.Bidirectional))]
- [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementRef, typeof({{marshallerName}}))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedIn, typeof({{marshallerFullName}}.ManagedToNative))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedOut, typeof({{marshallerFullName}}.ManagedToNative))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementIn, typeof({{marshallerFullName}}.ManagedToNative))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedOut, typeof({{marshallerFullName}}.NativeToManaged))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedIn, typeof({{marshallerFullName}}.NativeToManaged))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementOut, typeof({{marshallerFullName}}.NativeToManaged))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ManagedToUnmanagedRef, typeof({{marshallerFullName}}.Bidirectional))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.UnmanagedToManagedRef, typeof({{marshallerFullName}}.Bidirectional))]
+ [CustomMarshaller(typeof({{classInfo.Name}}), MarshalMode.ElementRef, typeof({{marshallerFullName}}))]
{{GenerateCSharpAccessLevel(classInfo.Access)}}static class {{marshallerName}}
{
#pragma warning disable 1591
@@ -1446,23 +1461,26 @@ namespace Flax.Build.Bindings
{
contents.AppendLine();
- // Namespace begin
- if (!string.IsNullOrEmpty(structureInfo.Namespace))
- {
- contents.AppendFormat("namespace ");
- contents.AppendLine(structureInfo.Namespace);
- contents.AppendLine("{");
- indent += " ";
- }
#if USE_NETCORE
// Generate blittable structure
string structNativeMarshaling = "";
if (UseCustomMarshalling(buildData, structureInfo, structureInfo))
{
+ // Namespace begin
+ string interopNamespace = "";
+ if (!string.IsNullOrEmpty(structureInfo.Namespace))
+ {
+ interopNamespace = $"{structureInfo.Namespace}.Interop";
+ contents.AppendLine($"namespace {interopNamespace}");
+ contents.AppendLine("{");
+ indent += " ";
+ }
+
// NOTE: Permanent FlaxEngine.Object GCHandles must not be released when marshalling from native to managed.
string marshallerName = structureInfo.Name + "Marshaller";
- structNativeMarshaling = $"[NativeMarshalling(typeof({marshallerName}))]";
+ string marshallerFullName = !string.IsNullOrEmpty(interopNamespace) ? $"{interopNamespace}.{marshallerName}" : marshallerName;
+ structNativeMarshaling = $"[NativeMarshalling(typeof({marshallerFullName}))]";
var toManagedContent = GetStringBuilder();
var toNativeContent = GetStringBuilder();
@@ -1624,7 +1642,7 @@ namespace Flax.Build.Bindings
if (internalType)
{
// Marshal blittable array elements back to original non-blittable elements
- string originalElementTypeMarshaller = originalElementType + "Marshaller";
+ string originalElementTypeMarshaller = (!string.IsNullOrEmpty(apiType?.Namespace) ? $"{apiType?.Namespace}.Interop." : "") + originalElementType + "Marshaller";
string internalElementType = $"{originalElementTypeMarshaller}.{originalElementType}Internal";
toManagedContent.AppendLine($"unmanaged.{fieldInfo.Name} != IntPtr.Zero ? NativeInterop.ConvertArray((Unsafe.As(ManagedHandle.FromIntPtr(unmanaged.{fieldInfo.Name}).Target)).ToSpan<{internalElementType}>(), {originalElementTypeMarshaller}.ToManaged) : null;");
toNativeContent.AppendLine($"managed.{fieldInfo.Name}?.Length > 0 ? ManagedHandle.ToIntPtr(ManagedArray.WrapNewArray(NativeInterop.ConvertArray(managed.{fieldInfo.Name}, {originalElementTypeMarshaller}.ToNative)), GCHandleType.Weak) : IntPtr.Zero;");
@@ -1707,15 +1725,15 @@ namespace Flax.Build.Bindings
/// Marshaller for type .
///
{{InsertHideInEditorSection()}}
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ManagedToUnmanagedIn, typeof({{marshallerName}}.ManagedToNative))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.UnmanagedToManagedOut, typeof({{marshallerName}}.ManagedToNative))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ElementIn, typeof({{marshallerName}}.ManagedToNative))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ManagedToUnmanagedOut, typeof({{marshallerName}}.NativeToManaged))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.UnmanagedToManagedIn, typeof({{marshallerName}}.NativeToManaged))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ElementOut, typeof({{marshallerName}}.NativeToManaged))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ManagedToUnmanagedRef, typeof({{marshallerName}}.Bidirectional))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.UnmanagedToManagedRef, typeof({{marshallerName}}.Bidirectional))]
- [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ElementRef, typeof({{marshallerName}}))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ManagedToUnmanagedIn, typeof({{marshallerFullName}}.ManagedToNative))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.UnmanagedToManagedOut, typeof({{marshallerFullName}}.ManagedToNative))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ElementIn, typeof({{marshallerFullName}}.ManagedToNative))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ManagedToUnmanagedOut, typeof({{marshallerFullName}}.NativeToManaged))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.UnmanagedToManagedIn, typeof({{marshallerFullName}}.NativeToManaged))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ElementOut, typeof({{marshallerFullName}}.NativeToManaged))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ManagedToUnmanagedRef, typeof({{marshallerFullName}}.Bidirectional))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.UnmanagedToManagedRef, typeof({{marshallerFullName}}.Bidirectional))]
+ [CustomMarshaller(typeof({{structureInfo.Name}}), MarshalMode.ElementRef, typeof({{marshallerFullName}}))]
{{GenerateCSharpAccessLevel(structureInfo.Access)}}static unsafe class {{marshallerName}}
{
#pragma warning disable 1591
@@ -1724,8 +1742,8 @@ namespace Flax.Build.Bindings
{{InsertHideInEditorSection()}}
public static class NativeToManaged
{
- public static {{structureInfo.Name}} ConvertToManaged({{structureInfo.Name}}Internal unmanaged) => {{marshallerName}}.ToManaged(unmanaged);
- public static {{structureInfo.Name}}Internal ConvertToUnmanaged({{structureInfo.Name}} managed) => {{marshallerName}}.ToNative(managed);
+ public static {{structureInfo.Name}} ConvertToManaged({{structureInfo.Name}}Internal unmanaged) => {{marshallerFullName}}.ToManaged(unmanaged);
+ public static {{structureInfo.Name}}Internal ConvertToUnmanaged({{structureInfo.Name}} managed) => {{marshallerFullName}}.ToNative(managed);
public static void Free({{structureInfo.Name}}Internal unmanaged)
{
{{freeContents2.Replace("\n", "\n" + " ").ToString().TrimEnd()}}
@@ -1734,9 +1752,9 @@ namespace Flax.Build.Bindings
{{InsertHideInEditorSection()}}
public static class ManagedToNative
{
- public static {{structureInfo.Name}} ConvertToManaged({{structureInfo.Name}}Internal unmanaged) => {{marshallerName}}.ToManaged(unmanaged);
- public static {{structureInfo.Name}}Internal ConvertToUnmanaged({{structureInfo.Name}} managed) => {{marshallerName}}.ToNative(managed);
- public static void Free({{structureInfo.Name}}Internal unmanaged) => {{marshallerName}}.Free(unmanaged);
+ public static {{structureInfo.Name}} ConvertToManaged({{structureInfo.Name}}Internal unmanaged) => {{marshallerFullName}}.ToManaged(unmanaged);
+ public static {{structureInfo.Name}}Internal ConvertToUnmanaged({{structureInfo.Name}} managed) => {{marshallerFullName}}.ToNative(managed);
+ public static void Free({{structureInfo.Name}}Internal unmanaged) => {{marshallerFullName}}.Free(unmanaged);
}
{{InsertHideInEditorSection()}}
public struct Bidirectional
@@ -1744,10 +1762,10 @@ namespace Flax.Build.Bindings
{{structureInfo.Name}} managed;
{{structureInfo.Name}}Internal unmanaged;
public void FromManaged({{structureInfo.Name}} managed) => this.managed = managed;
- public {{structureInfo.Name}}Internal ToUnmanaged() { unmanaged = {{marshallerName}}.ToNative(managed); return unmanaged; }
- //public void FromUnmanaged({{structureInfo.Name}}Internal unmanaged) { {{marshallerName}}.Free(this.unmanaged.Value); this.unmanaged = unmanaged; }
+ public {{structureInfo.Name}}Internal ToUnmanaged() { unmanaged = {{marshallerFullName}}.ToNative(managed); return unmanaged; }
+ //public void FromUnmanaged({{structureInfo.Name}}Internal unmanaged) { {{marshallerFullName}}.Free(this.unmanaged.Value); this.unmanaged = unmanaged; }
public void FromUnmanaged({{structureInfo.Name}}Internal unmanaged) => this.unmanaged = unmanaged;
- public {{structureInfo.Name}} ToManaged() { managed = {{marshallerName}}.ToManaged(unmanaged); return managed; }
+ public {{structureInfo.Name}} ToManaged() { managed = {{marshallerFullName}}.ToManaged(unmanaged); return managed; }
public void Free() => NativeToManaged.Free(unmanaged);
}
internal static {{structureInfo.Name}} ConvertToManaged({{structureInfo.Name}}Internal unmanaged) => ToManaged(unmanaged);
@@ -1781,8 +1799,23 @@ namespace Flax.Build.Bindings
PutStringBuilder(freeContents);
PutStringBuilder(freeContents2);
PutStringBuilder(structContents);
+
+ // Namespace end
+ if (!string.IsNullOrEmpty(structureInfo.Namespace))
+ {
+ contents.AppendLine("}");
+ indent = indent.Substring(0, indent.Length - 4);
+ }
}
#endif
+ // Namespace begin
+ if (!string.IsNullOrEmpty(structureInfo.Namespace))
+ {
+ contents.AppendLine($"namespace {structureInfo.Namespace}");
+ contents.AppendLine("{");
+ indent += " ";
+ }
+
// Struct docs
GenerateCSharpComment(contents, indent, structureInfo.Comment);
@@ -1974,8 +2007,7 @@ namespace Flax.Build.Bindings
// Namespace begin
if (!string.IsNullOrEmpty(enumInfo.Namespace))
{
- contents.AppendFormat("namespace ");
- contents.AppendLine(enumInfo.Namespace);
+ contents.AppendLine($"namespace {enumInfo.Namespace}");
contents.AppendLine("{");
indent += " ";
}
@@ -2021,10 +2053,11 @@ namespace Flax.Build.Bindings
{
// Begin
contents.AppendLine();
+ string interopNamespace = "";
if (!string.IsNullOrEmpty(interfaceInfo.Namespace))
{
- contents.AppendFormat("namespace ");
- contents.AppendLine(interfaceInfo.Namespace);
+ interopNamespace = $"{interfaceInfo.Namespace}.Interop";
+ contents.AppendLine($"namespace {interfaceInfo.Namespace}");
contents.AppendLine("{");
indent += " ";
}
@@ -2091,14 +2124,22 @@ namespace Flax.Build.Bindings
#if USE_NETCORE
{
+ if (!string.IsNullOrEmpty(interopNamespace))
+ {
+ contents.AppendLine("}");
+ contents.AppendLine($"namespace {interopNamespace}");
+ contents.AppendLine("{");
+ }
+
string marshallerName = interfaceInfo.Name + "Marshaller";
+ string marshallerFullName = !string.IsNullOrEmpty(interopNamespace) ? $"{interopNamespace}.{marshallerName}" : marshallerName;
contents.AppendLine();
contents.Append(indent).AppendLine("/// ");
contents.Append(indent).AppendLine($"/// Marshaller for type .");
contents.Append(indent).AppendLine("/// ");
if (buildData.Target != null & buildData.Target.IsEditor)
contents.Append(indent).AppendLine("[HideInEditor]");
- contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({interfaceInfo.Name}), MarshalMode.Default, typeof({marshallerName}))]");
+ contents.Append(indent).AppendLine($"[CustomMarshaller(typeof({interfaceInfo.Name}), MarshalMode.Default, typeof({marshallerFullName}))]");
contents.Append(indent).AppendLine($"public static class {marshallerName}");
contents.Append(indent).AppendLine("{");
contents.AppendLine("#pragma warning disable 1591");