Optimize scripting API bindings generation if loaded API from valid cache
This commit is contained in:
@@ -1028,9 +1028,6 @@ namespace Flax.Build.Bindings
|
||||
|
||||
private static void GenerateCSharp(BuildData buildData, ModuleInfo moduleInfo, ref BindingsResult bindings)
|
||||
{
|
||||
if (!bindings.UseBindings)
|
||||
return;
|
||||
|
||||
var contents = new StringBuilder();
|
||||
buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo);
|
||||
|
||||
@@ -1081,12 +1078,6 @@ namespace Flax.Build.Bindings
|
||||
// Save generated file
|
||||
contents.AppendLine("#endif");
|
||||
Utilities.WriteFileIfChanged(bindings.GeneratedCSharpFilePath, contents.ToString());
|
||||
|
||||
// Ensure that generated file is included into build
|
||||
if (!moduleBuildInfo.SourceFiles.Contains(bindings.GeneratedCSharpFilePath))
|
||||
{
|
||||
moduleBuildInfo.SourceFiles.Add(bindings.GeneratedCSharpFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
internal struct GuidInterop
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace Flax.Build.Bindings
|
||||
Module = moduleInfo.Module,
|
||||
Name = moduleInfo.Name,
|
||||
Namespace = moduleInfo.Namespace,
|
||||
Children = new List<ApiTypeInfo>(),
|
||||
IsFromCache = true,
|
||||
};
|
||||
try
|
||||
{
|
||||
|
||||
@@ -1656,10 +1656,10 @@ namespace Flax.Build.Bindings
|
||||
}
|
||||
}
|
||||
|
||||
private static bool GenerateCppType(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, object type)
|
||||
private static void GenerateCppType(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, object type)
|
||||
{
|
||||
if (type is ApiTypeInfo apiTypeInfo && apiTypeInfo.IsInBuild)
|
||||
return false;
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -1671,16 +1671,12 @@ namespace Flax.Build.Bindings
|
||||
GenerateCppInterface(buildData, contents, moduleInfo, interfaceInfo);
|
||||
else if (type is InjectCppCodeInfo injectCppCodeInfo)
|
||||
contents.AppendLine(injectCppCodeInfo.Code);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error($"Failed to generate C++ bindings for {type}.");
|
||||
throw;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void GenerateCppCppUsedNonPodTypes(BuildData buildData, ApiTypeInfo apiType)
|
||||
@@ -1728,21 +1724,16 @@ namespace Flax.Build.Bindings
|
||||
CppReferencesFiles.Add(fileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
var headerPos = contents.Length;
|
||||
|
||||
foreach (var child in moduleInfo.Children)
|
||||
{
|
||||
foreach (var apiTypeInfo in child.Children)
|
||||
{
|
||||
if (GenerateCppType(buildData, contents, moduleInfo, apiTypeInfo))
|
||||
bindings.UseBindings = true;
|
||||
GenerateCppType(buildData, contents, moduleInfo, apiTypeInfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (!bindings.UseBindings)
|
||||
return;
|
||||
|
||||
GenerateCppModuleSource?.Invoke(buildData, moduleInfo, contents);
|
||||
|
||||
{
|
||||
@@ -2036,7 +2027,7 @@ namespace Flax.Build.Bindings
|
||||
var binaryModuleSourcePath = Path.Combine(project.ProjectFolderPath, "Source", binaryModuleName + ".Gen.cpp");
|
||||
contents.AppendLine("// This code was auto-generated. Do not modify it.");
|
||||
contents.AppendLine();
|
||||
contents.AppendLine($"#include \"Engine/Scripting/BinaryModule.h\"");
|
||||
contents.AppendLine("#include \"Engine/Scripting/BinaryModule.h\"");
|
||||
contents.AppendLine($"#include \"{binaryModuleName}.Gen.h\"");
|
||||
contents.AppendLine();
|
||||
contents.AppendLine($"StaticallyLinkedBinaryModuleInitializer StaticallyLinkedBinaryModule{binaryModuleName}(GetBinaryModule{binaryModuleName});");
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Flax.Build.NativeCpp;
|
||||
@@ -65,7 +66,6 @@ namespace Flax.Build.Bindings
|
||||
Module = module,
|
||||
Name = module.BinaryModuleName,
|
||||
Namespace = string.Empty,
|
||||
Children = new List<ApiTypeInfo>(),
|
||||
};
|
||||
if (string.IsNullOrEmpty(moduleInfo.Name))
|
||||
throw new Exception("Module name cannot be empty.");
|
||||
@@ -479,41 +479,82 @@ namespace Flax.Build.Bindings
|
||||
throw new Exception($"Invalid #if/endif pairing in file '{fileInfo.Name}'. Failed to generate API bindings for it.");
|
||||
}
|
||||
|
||||
private static bool UseBindings(object type)
|
||||
{
|
||||
var apiTypeInfo = type as ApiTypeInfo;
|
||||
if (apiTypeInfo != null && apiTypeInfo.IsInBuild)
|
||||
return false;
|
||||
if ((type is ModuleInfo || type is FileInfo) && apiTypeInfo != null)
|
||||
{
|
||||
foreach (var child in apiTypeInfo.Children)
|
||||
{
|
||||
if (UseBindings(child))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return type is ClassInfo ||
|
||||
type is StructureInfo ||
|
||||
type is InterfaceInfo ||
|
||||
type is InjectCppCodeInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The API bindings generation utility that can produce scripting bindings for another languages to the native code.
|
||||
/// </summary>
|
||||
public static void GenerateBindings(BuildData buildData, Module module, ref BuildOptions moduleOptions, out BindingsResult bindings)
|
||||
{
|
||||
// Parse module (or load from cache)
|
||||
var moduleInfo = ParseModule(buildData, module, moduleOptions);
|
||||
bindings = new BindingsResult
|
||||
{
|
||||
UseBindings = UseBindings(moduleInfo),
|
||||
GeneratedCppFilePath = Path.Combine(moduleOptions.IntermediateFolder, module.Name + ".Bindings.Gen.cpp"),
|
||||
GeneratedCSharpFilePath = Path.Combine(moduleOptions.IntermediateFolder, module.Name + ".Bindings.Gen.cs"),
|
||||
};
|
||||
var moduleInfo = ParseModule(buildData, module, moduleOptions);
|
||||
|
||||
if (bindings.UseBindings)
|
||||
{
|
||||
buildData.Modules.TryGetValue(moduleInfo.Module, out var moduleBuildInfo);
|
||||
|
||||
// Ensure that generated files are included into build
|
||||
if (!moduleBuildInfo.SourceFiles.Contains(bindings.GeneratedCSharpFilePath))
|
||||
moduleBuildInfo.SourceFiles.Add(bindings.GeneratedCSharpFilePath);
|
||||
}
|
||||
|
||||
// Skip if module is cached (no scripting API changed)
|
||||
if (moduleInfo.IsFromCache)
|
||||
return;
|
||||
|
||||
// Process parsed API
|
||||
foreach (var child in moduleInfo.Children)
|
||||
using (new ProfileEventScope("Process"))
|
||||
{
|
||||
try
|
||||
foreach (var child in moduleInfo.Children)
|
||||
{
|
||||
foreach (var apiTypeInfo in child.Children)
|
||||
ProcessAndValidate(buildData, apiTypeInfo);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (child is FileInfo fileInfo)
|
||||
Log.Error($"Failed to validate '{fileInfo.Name}' file to generate bindings.");
|
||||
throw;
|
||||
try
|
||||
{
|
||||
foreach (var apiTypeInfo in child.Children)
|
||||
ProcessAndValidate(buildData, apiTypeInfo);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (child is FileInfo fileInfo)
|
||||
Log.Error($"Failed to validate '{fileInfo.Name}' file to generate bindings.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generate bindings for scripting
|
||||
Log.Verbose($"Generating API bindings for {module.Name} ({moduleInfo.Name})");
|
||||
GenerateCpp(buildData, moduleInfo, ref bindings);
|
||||
GenerateCSharp(buildData, moduleInfo, ref bindings);
|
||||
if (bindings.UseBindings)
|
||||
{
|
||||
Log.Verbose($"Generating API bindings for {module.Name} ({moduleInfo.Name})");
|
||||
using (new ProfileEventScope("Cpp"))
|
||||
GenerateCpp(buildData, moduleInfo, ref bindings);
|
||||
using (new ProfileEventScope("CSharp"))
|
||||
GenerateCSharp(buildData, moduleInfo, ref bindings);
|
||||
|
||||
// TODO: add support for extending this code and support generating bindings for other scripting languages
|
||||
// TODO: add support for extending this code and support generating bindings for other scripting languages
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Flax.Build.Bindings
|
||||
public class ModuleInfo : ApiTypeInfo
|
||||
{
|
||||
public Module Module;
|
||||
public bool IsFromCache;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user