diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs index 207f543cc..b8fa0b254 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs @@ -878,11 +878,15 @@ namespace Flax.Build.Bindings contents.Append("protected "); else if (fieldInfo.Access == AccessLevel.Private) contents.Append("private "); - if (fieldInfo.IsStatic) + if (fieldInfo.IsConstexpr) + contents.Append("const "); + else if (fieldInfo.IsStatic) contents.Append("static "); + var returnValueType = GenerateCSharpNativeToManaged(buildData, fieldInfo.Type, classInfo); contents.Append(returnValueType).Append(' ').Append(fieldInfo.Name); - if (!useUnmanaged) + + if (!useUnmanaged || fieldInfo.IsConstexpr) { var defaultValue = GenerateCSharpDefaultValueNativeToManaged(buildData, fieldInfo.DefaultValue, classInfo, fieldInfo.Type); if (!string.IsNullOrEmpty(defaultValue)) @@ -1156,7 +1160,9 @@ namespace Flax.Build.Bindings contents.Append("protected "); else if (fieldInfo.Access == AccessLevel.Private) contents.Append("private "); - if (fieldInfo.IsStatic) + if (fieldInfo.IsConstexpr) + contents.Append("const "); + else if (fieldInfo.IsStatic) contents.Append("static "); string type; @@ -1189,9 +1195,17 @@ namespace Flax.Build.Bindings type = GenerateCSharpNativeToManaged(buildData, fieldInfo.Type, structureInfo); contents.Append(type).Append(' ').Append(fieldInfo.Name); - // Static fields are using C++ static value accessed via getter function binding - if (fieldInfo.IsStatic) + if (fieldInfo.IsConstexpr) { + // Compile-time constant + var defaultValue = GenerateCSharpDefaultValueNativeToManaged(buildData, fieldInfo.DefaultValue, structureInfo, fieldInfo.Type); + if (!string.IsNullOrEmpty(defaultValue)) + contents.Append(" = ").Append(defaultValue); + contents.AppendLine(";"); + } + else if (fieldInfo.IsStatic) + { + // Static fields are using C++ static value accessed via getter function binding contents.AppendLine(); contents.AppendLine(indent + "{"); indent += " "; @@ -1386,7 +1400,7 @@ namespace Flax.Build.Bindings else if (type is InjectCodeInfo injectCodeInfo && string.Equals(injectCodeInfo.Lang, "csharp", StringComparison.OrdinalIgnoreCase)) { // `using` directives needs to go above the generated code - foreach(var code in injectCodeInfo.Code.Split(';')) + foreach (var code in injectCodeInfo.Code.Split(';')) { if (code.StartsWith("using")) CSharpUsedNamespaces.Add(code.Substring(6)); diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs index ae4b71271..32a35d1e9 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs @@ -19,7 +19,7 @@ namespace Flax.Build.Bindings partial class BindingsGenerator { private static readonly Dictionary TypeCache = new Dictionary(); - private const int CacheVersion = 14; + private const int CacheVersion = 15; internal static void Write(BinaryWriter writer, string e) { diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 2908695e0..e96365d8b 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1384,7 +1384,7 @@ namespace Flax.Build.Bindings private static bool GenerateCppAutoSerializationSkip(BuildData buildData, ApiTypeInfo caller, MemberInfo memberInfo, TypeInfo typeInfo) { - if (memberInfo.IsStatic) + if (memberInfo.IsStatic || memberInfo.IsConstexpr) return true; if (memberInfo.Access != AccessLevel.Public && !memberInfo.HasAttribute("Serialize")) return true; @@ -1691,7 +1691,7 @@ namespace Flax.Build.Bindings // Fields foreach (var fieldInfo in classInfo.Fields) { - if (!useScripting || !useCSharp || fieldInfo.IsHidden) + if (!useScripting || !useCSharp || fieldInfo.IsHidden || fieldInfo.IsConstexpr) continue; if (fieldInfo.Getter != null) GenerateCppWrapperFunction(buildData, contents, classInfo, fieldInfo.Getter, "{0}"); @@ -1853,6 +1853,9 @@ namespace Flax.Build.Bindings // Fields foreach (var fieldInfo in structureInfo.Fields) { + if (fieldInfo.IsConstexpr) + continue; + // Static fields are using C++ static value accessed via getter function binding if (fieldInfo.IsStatic) { @@ -1977,7 +1980,7 @@ namespace Flax.Build.Bindings for (var i = 0; i < structureInfo.Fields.Count; i++) { var fieldInfo = structureInfo.Fields[i]; - if (fieldInfo.IsReadOnly || fieldInfo.IsStatic || fieldInfo.Access == AccessLevel.Private) + if (fieldInfo.IsReadOnly || fieldInfo.IsStatic || fieldInfo.IsConstexpr || fieldInfo.Access == AccessLevel.Private) continue; if (i == 0) contents.AppendLine($" if (name == TEXT(\"{fieldInfo.Name}\"))"); @@ -1993,7 +1996,7 @@ namespace Flax.Build.Bindings for (var i = 0; i < structureInfo.Fields.Count; i++) { var fieldInfo = structureInfo.Fields[i]; - if (fieldInfo.IsReadOnly || fieldInfo.IsStatic || fieldInfo.Access == AccessLevel.Private) + if (fieldInfo.IsReadOnly || fieldInfo.IsStatic || fieldInfo.IsConstexpr || fieldInfo.Access == AccessLevel.Private) continue; if (i == 0) contents.AppendLine($" if (name == TEXT(\"{fieldInfo.Name}\"))"); @@ -2205,7 +2208,7 @@ namespace Flax.Build.Bindings for (var i = 0; i < structureInfo.Fields.Count; i++) { var fieldInfo = structureInfo.Fields[i]; - if (fieldInfo.IsStatic) + if (fieldInfo.IsStatic || fieldInfo.IsConstexpr) continue; var fieldType = fieldInfo.Type; var fieldApiType = FindApiTypeInfo(buildData, fieldType, structureInfo); @@ -2450,7 +2453,7 @@ namespace Flax.Build.Bindings for (var i = 0; i < fields.Count; i++) { var fieldInfo = fields[i]; - if (fieldInfo.IsStatic) + if (fieldInfo.IsStatic || fieldInfo.IsConstexpr) continue; if (fieldInfo.NoArray && fieldInfo.Type.IsArray) @@ -2482,7 +2485,7 @@ namespace Flax.Build.Bindings for (var i = 0; i < fields.Count; i++) { var fieldInfo = fields[i]; - if (fieldInfo.IsStatic) + if (fieldInfo.IsStatic || fieldInfo.IsConstexpr) continue; CppNonPodTypesConvertingGeneration = true; @@ -2531,7 +2534,7 @@ namespace Flax.Build.Bindings for (var i = 0; i < fields.Count; i++) { var fieldInfo = fields[i]; - if (fieldInfo.IsStatic) + if (fieldInfo.IsStatic || fieldInfo.IsConstexpr) continue; if (fieldInfo.NoArray && fieldInfo.Type.IsArray) @@ -2566,7 +2569,7 @@ namespace Flax.Build.Bindings for (var i = 0; i < fields.Count; i++) { var fieldInfo = fields[i]; - if (fieldInfo.IsStatic) + if (fieldInfo.IsStatic || fieldInfo.IsConstexpr) continue; CppNonPodTypesConvertingGeneration = true; diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs index 457787a22..e9c017692 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs @@ -1155,6 +1155,11 @@ namespace Flax.Build.Bindings desc.IsStatic = true; context.Tokenizer.NextToken(); } + else if (!desc.IsConstexpr && token.Value == "constexpr") + { + desc.IsConstexpr = true; + context.Tokenizer.NextToken(); + } else if (!isMutable && token.Value == "mutable") { isMutable = true; diff --git a/Source/Tools/Flax.Build/Bindings/MemberInfo.cs b/Source/Tools/Flax.Build/Bindings/MemberInfo.cs index 842aa2f54..1422e25a7 100644 --- a/Source/Tools/Flax.Build/Bindings/MemberInfo.cs +++ b/Source/Tools/Flax.Build/Bindings/MemberInfo.cs @@ -12,6 +12,7 @@ namespace Flax.Build.Bindings public string Name; public string[] Comment; public bool IsStatic; + public bool IsConstexpr; public bool IsDeprecated; public bool IsHidden; public AccessLevel Access; @@ -27,6 +28,7 @@ namespace Flax.Build.Bindings writer.Write(Name); BindingsGenerator.Write(writer, Comment); writer.Write(IsStatic); + writer.Write(IsConstexpr); writer.Write(IsDeprecated); writer.Write(IsHidden); writer.Write((byte)Access); @@ -38,6 +40,7 @@ namespace Flax.Build.Bindings Name = reader.ReadString(); Comment = BindingsGenerator.Read(reader, Comment); IsStatic = reader.ReadBoolean(); + IsConstexpr = reader.ReadBoolean(); IsDeprecated = reader.ReadBoolean(); IsHidden = reader.ReadBoolean(); Access = (AccessLevel)reader.ReadByte();