Add API_INTERFACE to scripting API bindings for implementing interfaces
This commit is contained in:
@@ -22,6 +22,7 @@ namespace Flax.Build.Bindings
|
||||
public virtual bool IsClass => false;
|
||||
public virtual bool IsStruct => false;
|
||||
public virtual bool IsEnum => false;
|
||||
public virtual bool IsInterface => false;
|
||||
public virtual bool IsValueType => false;
|
||||
public virtual bool IsScriptingObject => false;
|
||||
public virtual bool IsPod => false;
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
public static readonly string Enum = "API_ENUM";
|
||||
public static readonly string Class = "API_CLASS";
|
||||
public static readonly string Interface = "API_INTERFACE";
|
||||
public static readonly string Struct = "API_STRUCT";
|
||||
public static readonly string Function = "API_FUNCTION";
|
||||
public static readonly string Property = "API_PROPERTY";
|
||||
@@ -27,6 +28,7 @@ namespace Flax.Build.Bindings
|
||||
Enum,
|
||||
Class,
|
||||
Struct,
|
||||
Interface,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -947,9 +947,7 @@ namespace Flax.Build.Bindings
|
||||
var classInfo = typeInfo as ClassInfo;
|
||||
var structureInfo = typeInfo as StructureInfo;
|
||||
var baseType = classInfo?.BaseType ?? structureInfo?.BaseType;
|
||||
if (baseType != null && baseType.Type == "ISerializable")
|
||||
baseType = null;
|
||||
else if (classInfo != null && classInfo.IsBaseTypeHidden)
|
||||
if (classInfo != null && classInfo.IsBaseTypeHidden)
|
||||
baseType = null;
|
||||
CppAutoSerializeFields.Clear();
|
||||
CppAutoSerializeProperties.Clear();
|
||||
@@ -1038,6 +1036,25 @@ namespace Flax.Build.Bindings
|
||||
contents.Append('}').AppendLine();
|
||||
}
|
||||
|
||||
private static string GenerateCppInterfaceInheritanceTable(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, ClassStructInfo typeInfo, string typeNameNative)
|
||||
{
|
||||
var interfacesPtr = "nullptr";
|
||||
var interfaces = typeInfo.Interfaces;
|
||||
if (interfaces != null)
|
||||
{
|
||||
interfacesPtr = typeNameNative + "_Interfaces";
|
||||
contents.Append("static const ScriptingType::InterfaceImplementation ").Append(interfacesPtr).AppendLine("[] = {");
|
||||
for (int i = 0; i < interfaces.Count; i++)
|
||||
{
|
||||
var interfaceInfo = interfaces[i];
|
||||
contents.Append(" { &").Append(interfaceInfo.NativeName).Append("::TypeInitializer, (int16)VTABLE_OFFSET(").Append(typeInfo.NativeName).Append(", ").Append(interfaceInfo.NativeName).AppendLine(") },");
|
||||
}
|
||||
contents.AppendLine(" { nullptr, 0 },");
|
||||
contents.AppendLine("};");
|
||||
}
|
||||
return interfacesPtr;
|
||||
}
|
||||
|
||||
private static void GenerateCppClass(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, ClassInfo classInfo)
|
||||
{
|
||||
var classTypeNameNative = classInfo.FullNameNative;
|
||||
@@ -1311,6 +1328,9 @@ namespace Flax.Build.Bindings
|
||||
contents.Append('}').Append(';').AppendLine();
|
||||
contents.AppendLine();
|
||||
|
||||
// Interfaces
|
||||
var interfacesTable = GenerateCppInterfaceInheritanceTable(buildData, contents, moduleInfo, classInfo, classTypeNameNative);
|
||||
|
||||
// Type initializer
|
||||
contents.Append($"ScriptingTypeInitializer {classTypeNameNative}::TypeInitializer((BinaryModule*)GetBinaryModule{moduleInfo.Name}(), ");
|
||||
contents.Append($"StringAnsiView(\"{classTypeNameManaged}\", {classTypeNameManaged.Length}), ");
|
||||
@@ -1330,8 +1350,9 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
else
|
||||
{
|
||||
contents.Append($"&{classTypeNameInternal}Internal::Ctor, &{classTypeNameInternal}Internal::Dtor");
|
||||
contents.Append($"&{classTypeNameInternal}Internal::Ctor, &{classTypeNameInternal}Internal::Dtor, nullptr");
|
||||
}
|
||||
contents.Append(", ").Append(interfacesTable);
|
||||
contents.Append(");");
|
||||
contents.AppendLine();
|
||||
|
||||
@@ -1526,6 +1547,42 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateCppInterface(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, InterfaceInfo interfaceInfo)
|
||||
{
|
||||
var interfaceTypeNameNative = interfaceInfo.FullNameNative;
|
||||
var interfaceTypeNameManaged = interfaceInfo.FullNameManaged;
|
||||
var interfaceTypeNameManagedInternalCall = interfaceTypeNameManaged.Replace('+', '/');
|
||||
var interfaceTypeNameInternal = interfaceInfo.NativeName;
|
||||
if (interfaceInfo.Parent != null && !(interfaceInfo.Parent is FileInfo))
|
||||
interfaceTypeNameInternal = interfaceInfo.Parent.FullNameNative + '_' + interfaceTypeNameInternal;
|
||||
|
||||
contents.AppendLine();
|
||||
contents.AppendFormat("class {0}Internal", interfaceTypeNameInternal).AppendLine();
|
||||
contents.Append('{').AppendLine();
|
||||
contents.AppendLine("public:");
|
||||
|
||||
// Runtime initialization (internal methods binding)
|
||||
contents.AppendLine(" static void InitRuntime()");
|
||||
contents.AppendLine(" {");
|
||||
contents.AppendLine(" }").AppendLine();
|
||||
|
||||
contents.Append('}').Append(';').AppendLine();
|
||||
contents.AppendLine();
|
||||
|
||||
// Type initializer
|
||||
contents.Append($"ScriptingTypeInitializer {interfaceTypeNameNative}::TypeInitializer((BinaryModule*)GetBinaryModule{moduleInfo.Name}(), ");
|
||||
contents.Append($"StringAnsiView(\"{interfaceTypeNameManaged}\", {interfaceTypeNameManaged.Length}), ");
|
||||
contents.Append($"&{interfaceTypeNameInternal}Internal::InitRuntime");
|
||||
contents.Append(");");
|
||||
contents.AppendLine();
|
||||
|
||||
// Nested types
|
||||
foreach (var apiTypeInfo in interfaceInfo.Children)
|
||||
{
|
||||
GenerateCppType(buildData, contents, moduleInfo, apiTypeInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private static bool GenerateCppType(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, object type)
|
||||
{
|
||||
if (type is ApiTypeInfo apiTypeInfo && apiTypeInfo.IsInBuild)
|
||||
@@ -1537,6 +1594,8 @@ namespace Flax.Build.Bindings
|
||||
GenerateCppClass(buildData, contents, moduleInfo, classInfo);
|
||||
else if (type is StructureInfo structureInfo)
|
||||
GenerateCppStruct(buildData, contents, moduleInfo, structureInfo);
|
||||
else if (type is InterfaceInfo interfaceInfo)
|
||||
GenerateCppInterface(buildData, contents, moduleInfo, interfaceInfo);
|
||||
else if (type is InjectCppCodeInfo injectCppCodeInfo)
|
||||
contents.AppendLine(injectCppCodeInfo.Code);
|
||||
else
|
||||
|
||||
@@ -383,6 +383,95 @@ namespace Flax.Build.Bindings
|
||||
return name;
|
||||
}
|
||||
|
||||
private static void ParseInheritance(ref ParsingContext context, ClassStructInfo desc, out bool isFinal)
|
||||
{
|
||||
desc.BaseType = null;
|
||||
desc.BaseTypeInheritance = AccessLevel.Private;
|
||||
|
||||
var token = context.Tokenizer.NextToken();
|
||||
isFinal = token.Value == "final";
|
||||
if (isFinal)
|
||||
token = context.Tokenizer.NextToken();
|
||||
|
||||
if (token.Type == TokenType.Colon)
|
||||
{
|
||||
while (token.Type != TokenType.LeftCurlyBrace)
|
||||
{
|
||||
var accessToken = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
switch (accessToken.Value)
|
||||
{
|
||||
case "public":
|
||||
desc.BaseTypeInheritance = AccessLevel.Public;
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
case "protected":
|
||||
desc.BaseTypeInheritance = AccessLevel.Protected;
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
case "private":
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
default:
|
||||
token = accessToken;
|
||||
break;
|
||||
}
|
||||
|
||||
var baseTypeInfo = new TypeInfo
|
||||
{
|
||||
Type = token.Value,
|
||||
};
|
||||
if (token.Value.Length > 2 && token.Value[0] == 'I' && char.IsUpper(token.Value[1]))
|
||||
{
|
||||
// Interface
|
||||
if (desc.InterfaceNames == null)
|
||||
desc.InterfaceNames = new List<TypeInfo>();
|
||||
desc.InterfaceNames.Add(baseTypeInfo);
|
||||
token = context.Tokenizer.NextToken();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (desc.BaseType != null)
|
||||
{
|
||||
// Allow for multiple base classes, just the first one needs to be a valid base type
|
||||
break;
|
||||
throw new Exception($"Invalid '{desc.Name}' inheritance (only single base class is allowed for scripting types, excluding interfaces).");
|
||||
}
|
||||
desc.BaseType = baseTypeInfo;
|
||||
token = context.Tokenizer.NextToken();
|
||||
if (token.Type == TokenType.LeftCurlyBrace)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (token.Type == TokenType.LeftAngleBracket)
|
||||
{
|
||||
var genericType = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
token = context.Tokenizer.ExpectToken(TokenType.RightAngleBracket);
|
||||
desc.BaseType.GenericArgs = new List<TypeInfo>
|
||||
{
|
||||
new TypeInfo
|
||||
{
|
||||
Type = genericType.Value,
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: find better way to resolve this (custom base type attribute?)
|
||||
if (desc.BaseType.Type == "ShaderAssetTypeBase")
|
||||
{
|
||||
desc.BaseType = desc.BaseType.GenericArgs[0];
|
||||
}
|
||||
|
||||
token = context.Tokenizer.NextToken();
|
||||
}
|
||||
}
|
||||
token = context.Tokenizer.PreviousToken();
|
||||
}
|
||||
else
|
||||
{
|
||||
// No base type
|
||||
token = context.Tokenizer.PreviousToken();
|
||||
}
|
||||
}
|
||||
|
||||
private static ClassInfo ParseClass(ref ParsingContext context)
|
||||
{
|
||||
var desc = new ClassInfo
|
||||
@@ -410,64 +499,8 @@ namespace Flax.Build.Bindings
|
||||
// Read name
|
||||
desc.Name = desc.NativeName = ParseName(ref context);
|
||||
|
||||
// Read class inheritance
|
||||
token = context.Tokenizer.NextToken();
|
||||
var isFinal = token.Value == "final";
|
||||
if (isFinal)
|
||||
token = context.Tokenizer.NextToken();
|
||||
if (token.Type == TokenType.Colon)
|
||||
{
|
||||
// Current class does have inheritance defined
|
||||
var accessToken = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
switch (accessToken.Value)
|
||||
{
|
||||
case "public":
|
||||
desc.BaseTypeInheritance = AccessLevel.Public;
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
case "protected":
|
||||
desc.BaseTypeInheritance = AccessLevel.Protected;
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
case "private":
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
}
|
||||
|
||||
desc.BaseType = new TypeInfo
|
||||
{
|
||||
Type = token.Value,
|
||||
};
|
||||
token = context.Tokenizer.NextToken();
|
||||
if (token.Type == TokenType.LeftAngleBracket)
|
||||
{
|
||||
var genericType = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
context.Tokenizer.ExpectToken(TokenType.RightAngleBracket);
|
||||
desc.BaseType.GenericArgs = new List<TypeInfo>
|
||||
{
|
||||
new TypeInfo
|
||||
{
|
||||
Type = genericType.Value,
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: find better way to resolve this (custom base type attribute?)
|
||||
if (desc.BaseType.Type == "ShaderAssetTypeBase")
|
||||
{
|
||||
desc.BaseType = desc.BaseType.GenericArgs[0];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
token = context.Tokenizer.PreviousToken();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No base type
|
||||
token = context.Tokenizer.PreviousToken();
|
||||
desc.BaseType = null;
|
||||
}
|
||||
// Read inheritance
|
||||
ParseInheritance(ref context, desc, out var isFinal);
|
||||
|
||||
// Process tag parameters
|
||||
foreach (var tag in tagParams)
|
||||
@@ -523,6 +556,68 @@ namespace Flax.Build.Bindings
|
||||
return desc;
|
||||
}
|
||||
|
||||
private static InterfaceInfo ParseInterface(ref ParsingContext context)
|
||||
{
|
||||
var desc = new InterfaceInfo
|
||||
{
|
||||
Children = new List<ApiTypeInfo>(),
|
||||
Access = context.CurrentAccessLevel,
|
||||
};
|
||||
|
||||
// Read the documentation comment
|
||||
desc.Comment = ParseComment(ref context);
|
||||
|
||||
// Read parameters from the tag
|
||||
var tagParams = ParseTagParameters(ref context);
|
||||
|
||||
// Read 'class' keyword
|
||||
var token = context.Tokenizer.NextToken();
|
||||
if (token.Value != "class")
|
||||
throw new Exception($"Invalid API_INTERFACE usage (expected 'class' keyword but got '{token.Value} {context.Tokenizer.NextToken().Value}').");
|
||||
|
||||
// Read name
|
||||
desc.Name = desc.NativeName = ParseName(ref context);
|
||||
if (desc.Name.Length < 2 || desc.Name[0] != 'I' || !char.IsUpper(desc.Name[1]))
|
||||
throw new Exception($"Invalid API_INTERFACE name '{desc.Name}' (it must start with 'I' character followed by the uppercase character).");
|
||||
|
||||
// Read inheritance
|
||||
ParseInheritance(ref context, desc, out _);
|
||||
|
||||
// Process tag parameters
|
||||
foreach (var tag in tagParams)
|
||||
{
|
||||
switch (tag.Tag.ToLower())
|
||||
{
|
||||
case "public":
|
||||
desc.Access = AccessLevel.Public;
|
||||
break;
|
||||
case "protected":
|
||||
desc.Access = AccessLevel.Protected;
|
||||
break;
|
||||
case "private":
|
||||
desc.Access = AccessLevel.Private;
|
||||
break;
|
||||
case "inbuild":
|
||||
desc.IsInBuild = true;
|
||||
break;
|
||||
case "attributes":
|
||||
desc.Attributes = tag.Value;
|
||||
break;
|
||||
case "name":
|
||||
desc.Name = tag.Value;
|
||||
break;
|
||||
case "namespace":
|
||||
desc.Namespace = tag.Value;
|
||||
break;
|
||||
default:
|
||||
Log.Warning($"Unknown or not supported tag parameter {tag} used on interface {desc.Name} at line {context.Tokenizer.CurrentLine}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return desc;
|
||||
}
|
||||
|
||||
private static FunctionInfo ParseFunction(ref ParsingContext context)
|
||||
{
|
||||
var desc = new FunctionInfo
|
||||
@@ -875,55 +970,8 @@ namespace Flax.Build.Bindings
|
||||
// Read name
|
||||
desc.Name = desc.NativeName = ParseName(ref context);
|
||||
|
||||
// Read structure inheritance
|
||||
token = context.Tokenizer.NextToken();
|
||||
if (token.Type == TokenType.Colon)
|
||||
{
|
||||
// Current class does have inheritance defined
|
||||
var accessToken = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
switch (accessToken.Value)
|
||||
{
|
||||
case "public":
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
case "protected":
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
case "private":
|
||||
token = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
break;
|
||||
default:
|
||||
token = accessToken;
|
||||
break;
|
||||
}
|
||||
|
||||
desc.BaseType = new TypeInfo
|
||||
{
|
||||
Type = token.Value,
|
||||
};
|
||||
token = context.Tokenizer.NextToken();
|
||||
if (token.Type == TokenType.LeftAngleBracket)
|
||||
{
|
||||
var genericType = context.Tokenizer.ExpectToken(TokenType.Identifier);
|
||||
context.Tokenizer.ExpectToken(TokenType.RightAngleBracket);
|
||||
desc.BaseType.GenericArgs = new List<TypeInfo>
|
||||
{
|
||||
new TypeInfo
|
||||
{
|
||||
Type = genericType.Value,
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
token = context.Tokenizer.PreviousToken();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No base type
|
||||
token = context.Tokenizer.PreviousToken();
|
||||
}
|
||||
// Read inheritance
|
||||
ParseInheritance(ref context, desc, out _);
|
||||
|
||||
// Process tag parameters
|
||||
foreach (var tag in tagParams)
|
||||
|
||||
@@ -254,6 +254,16 @@ namespace Flax.Build.Bindings
|
||||
var injectCppCodeInfo = ParseInjectCppCode(ref context);
|
||||
fileInfo.AddChild(injectCppCodeInfo);
|
||||
}
|
||||
else if (string.Equals(token.Value, ApiTokens.Interface, StringComparison.Ordinal))
|
||||
{
|
||||
if (!(context.ScopeInfo is FileInfo))
|
||||
throw new NotImplementedException("TODO: add support for nested interfaces in scripting API");
|
||||
|
||||
var interfaceInfo = ParseInterface(ref context);
|
||||
scopeType = interfaceInfo;
|
||||
context.ScopeInfo.AddChild(scopeType);
|
||||
context.CurrentAccessLevel = AccessLevel.Public;
|
||||
}
|
||||
else if (string.Equals(token.Value, ApiTokens.AutoSerialization, StringComparison.Ordinal))
|
||||
{
|
||||
if (context.ScopeInfo is ClassInfo classInfo)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2012-2019 Wojciech Figat. All rights reserved.
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -8,7 +8,7 @@ namespace Flax.Build.Bindings
|
||||
/// <summary>
|
||||
/// The native class information for bindings generator.
|
||||
/// </summary>
|
||||
public class ClassInfo : ApiTypeInfo
|
||||
public class ClassInfo : ClassStructInfo
|
||||
{
|
||||
private static readonly HashSet<string> InBuildScriptingObjectTypes = new HashSet<string>
|
||||
{
|
||||
@@ -22,9 +22,6 @@ namespace Flax.Build.Bindings
|
||||
"Actor",
|
||||
};
|
||||
|
||||
public AccessLevel Access;
|
||||
public TypeInfo BaseType;
|
||||
public AccessLevel BaseTypeInheritance;
|
||||
public bool IsBaseTypeHidden;
|
||||
public bool IsStatic;
|
||||
public bool IsSealed;
|
||||
@@ -52,7 +49,7 @@ namespace Flax.Build.Bindings
|
||||
base.Init(buildData);
|
||||
|
||||
// Internal base types are usually hidden from bindings (used in core-only internally)
|
||||
IsBaseTypeHidden = BaseTypeInheritance == AccessLevel.Private || BaseType.Type == "ISerializable";
|
||||
IsBaseTypeHidden = BaseTypeInheritance == AccessLevel.Private || BaseType == null;
|
||||
|
||||
// Cache if it it Scripting Object type
|
||||
if (InBuildScriptingObjectTypes.Contains(Name))
|
||||
|
||||
40
Source/Tools/Flax.Build/Bindings/ClassStructInfo.cs
Normal file
40
Source/Tools/Flax.Build/Bindings/ClassStructInfo.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Flax.Build.Bindings
|
||||
{
|
||||
/// <summary>
|
||||
/// The native class/structure information for bindings generator.
|
||||
/// </summary>
|
||||
public abstract class ClassStructInfo : ApiTypeInfo
|
||||
{
|
||||
public AccessLevel Access;
|
||||
public AccessLevel BaseTypeInheritance;
|
||||
public TypeInfo BaseType;
|
||||
public List<InterfaceInfo> Interfaces; // Optional
|
||||
public List<TypeInfo> InterfaceNames; // Optional
|
||||
|
||||
public override void Init(Builder.BuildData buildData)
|
||||
{
|
||||
base.Init(buildData);
|
||||
|
||||
if (Interfaces == null && InterfaceNames != null && InterfaceNames.Count != 0)
|
||||
{
|
||||
Interfaces = new List<InterfaceInfo>();
|
||||
for (var i = 0; i < InterfaceNames.Count; i++)
|
||||
{
|
||||
var interfaceName = InterfaceNames[i];
|
||||
var apiTypeInfo = BindingsGenerator.FindApiTypeInfo(buildData, interfaceName, this);
|
||||
if (apiTypeInfo is InterfaceInfo interfaceInfo)
|
||||
{
|
||||
Interfaces.Add(interfaceInfo);
|
||||
}
|
||||
}
|
||||
if (Interfaces.Count == 0)
|
||||
Interfaces = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Source/Tools/Flax.Build/Bindings/InterfaceInfo.cs
Normal file
24
Source/Tools/Flax.Build/Bindings/InterfaceInfo.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace Flax.Build.Bindings
|
||||
{
|
||||
/// <summary>
|
||||
/// The native class/structure interface information for bindings generator.
|
||||
/// </summary>
|
||||
public class InterfaceInfo : ClassStructInfo
|
||||
{
|
||||
public override bool IsInterface => true;
|
||||
|
||||
public override void AddChild(ApiTypeInfo apiTypeInfo)
|
||||
{
|
||||
apiTypeInfo.Namespace = null;
|
||||
|
||||
base.AddChild(apiTypeInfo);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "interface " + Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,8 @@ namespace Flax.Build.Bindings
|
||||
/// <summary>
|
||||
/// The native structure information for bindings generator.
|
||||
/// </summary>
|
||||
public class StructureInfo : ApiTypeInfo
|
||||
public class StructureInfo : ClassStructInfo
|
||||
{
|
||||
public AccessLevel Access;
|
||||
public TypeInfo BaseType;
|
||||
public List<FieldInfo> Fields;
|
||||
public List<FunctionInfo> Functions;
|
||||
public bool IsAutoSerialization;
|
||||
@@ -27,7 +25,7 @@ namespace Flax.Build.Bindings
|
||||
{
|
||||
base.Init(buildData);
|
||||
|
||||
if (ForceNoPod)
|
||||
if (ForceNoPod || (InterfaceNames != null && InterfaceNames.Count != 0))
|
||||
{
|
||||
_isPod = false;
|
||||
return;
|
||||
|
||||
@@ -69,12 +69,14 @@
|
||||
<Compile Include="Bindings\BindingsGenerator.CSharp.cs" />
|
||||
<Compile Include="Bindings\BindingsGenerator.Parsing.cs" />
|
||||
<Compile Include="Bindings\ClassInfo.cs" />
|
||||
<Compile Include="Bindings\ClassStructInfo.cs" />
|
||||
<Compile Include="Bindings\EnumInfo.cs" />
|
||||
<Compile Include="Bindings\EventInfo.cs" />
|
||||
<Compile Include="Bindings\FieldInfo.cs" />
|
||||
<Compile Include="Bindings\FileInfo.cs" />
|
||||
<Compile Include="Bindings\InheritanceInfo.cs" />
|
||||
<Compile Include="Bindings\InjectCppCodeInfo.cs" />
|
||||
<Compile Include="Bindings\InterfaceInfo.cs" />
|
||||
<Compile Include="Bindings\LangType.cs" />
|
||||
<Compile Include="Bindings\MemberInfo.cs" />
|
||||
<Compile Include="Bindings\FunctionInfo.cs" />
|
||||
|
||||
Reference in New Issue
Block a user