diff --git a/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs b/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs
index 814983e9b..3e2ad1b31 100644
--- a/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/ApiTypeInfo.cs
@@ -1,16 +1,17 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
+using System.IO;
namespace Flax.Build.Bindings
{
///
/// The native type information for bindings generator.
///
- public class ApiTypeInfo
+ public class ApiTypeInfo : IBindingsCache
{
public ApiTypeInfo Parent;
- public List Children;
+ public List Children = new List();
public string NativeName;
public string Name;
public string Namespace;
@@ -91,6 +92,35 @@ namespace Flax.Build.Bindings
Children.Add(apiTypeInfo);
}
+ public virtual void Write(BinaryWriter writer)
+ {
+ BindingsGenerator.Write(writer, NativeName);
+ BindingsGenerator.Write(writer, Name);
+ BindingsGenerator.Write(writer, Namespace);
+ BindingsGenerator.Write(writer, Attributes);
+ BindingsGenerator.Write(writer, Comment);
+ writer.Write(IsInBuild);
+ BindingsGenerator.Write(writer, Children);
+ }
+
+ public virtual void Read(BinaryReader reader)
+ {
+ NativeName = BindingsGenerator.Read(reader, NativeName);
+ Name = BindingsGenerator.Read(reader, Name);
+ Namespace = BindingsGenerator.Read(reader, Namespace);
+ Attributes = BindingsGenerator.Read(reader, Attributes);
+ Comment = BindingsGenerator.Read(reader, Comment);
+ IsInBuild = reader.ReadBoolean();
+ Children = BindingsGenerator.Read(reader, Children);
+
+ // Fix hierarchy
+ for (int i = 0; i < Children.Count; i++)
+ {
+ var child = Children[i];
+ child.Parent = this;
+ }
+ }
+
public override string ToString()
{
return Name;
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
index d9dc61521..2fd6a6edd 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.CSharp.cs
@@ -521,6 +521,7 @@ namespace Flax.Build.Bindings
{
if (!useUnmanaged)
throw new NotImplementedException("TODO: support events inside non-static and non-scripting API class types.");
+ var paramsCount = eventInfo.Type.GenericArgs?.Count ?? 0;
contents.AppendLine();
@@ -542,10 +543,10 @@ namespace Flax.Build.Bindings
if (eventInfo.IsStatic)
contents.Append("static ");
string eventSignature = "event Action";
- if (eventInfo.Type.GenericArgs.Count != 0)
+ if (paramsCount != 0)
{
eventSignature += '<';
- for (var i = 0; i < eventInfo.Type.GenericArgs.Count; i++)
+ for (var i = 0; i < paramsCount; i++)
{
if (i != 0)
eventSignature += ", ";
@@ -583,7 +584,7 @@ namespace Flax.Build.Bindings
if (eventInfo.IsStatic)
contents.Append("static ");
contents.Append($"void Internal_{eventInfo.Name}_Invoke(");
- for (var i = 0; i < eventInfo.Type.GenericArgs.Count; i++)
+ for (var i = 0; i < paramsCount; i++)
{
if (i != 0)
contents.Append(", ");
@@ -594,7 +595,7 @@ namespace Flax.Build.Bindings
contents.Append(indent).Append('{').AppendLine();
contents.Append(indent).Append(" Internal_").Append(eventInfo.Name);
contents.Append('(');
- for (var i = 0; i < eventInfo.Type.GenericArgs.Count; i++)
+ for (var i = 0; i < paramsCount; i++)
{
if (i != 0)
contents.Append(", ");
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs
new file mode 100644
index 000000000..bc141759c
--- /dev/null
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cache.cs
@@ -0,0 +1,266 @@
+// (c) 2012-2020 Wojciech Figat. All rights reserved.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Flax.Build.NativeCpp;
+
+namespace Flax.Build.Bindings
+{
+ internal interface IBindingsCache
+ {
+ void Write(BinaryWriter writer);
+ void Read(BinaryReader reader);
+ }
+
+ partial class BindingsGenerator
+ {
+ private static readonly Dictionary _typeCache = new Dictionary();
+
+ internal static void Write(BinaryWriter writer, string e)
+ {
+ var valid = e != null;
+ writer.Write(valid);
+ if (valid)
+ writer.Write(e);
+ }
+
+ internal static void Write(BinaryWriter writer, string[] list)
+ {
+ if (list != null)
+ {
+ writer.Write(list.Length);
+ for (int i = 0; i < list.Length; i++)
+ writer.Write(list[i]);
+ }
+ else
+ {
+ writer.Write(0);
+ }
+ }
+
+ internal static void Write(BinaryWriter writer, IEnumerable list)
+ {
+ if (list != null)
+ {
+ writer.Write(list.Count());
+ foreach (var e in list)
+ writer.Write(e);
+ }
+ else
+ {
+ writer.Write(0);
+ }
+ }
+
+ internal static void Write(BinaryWriter writer, T e) where T : IBindingsCache
+ {
+ if (e != null)
+ {
+ writer.Write(e.GetType().FullName);
+ e.Write(writer);
+ }
+ else
+ {
+ writer.Write(string.Empty);
+ }
+ }
+
+ internal static void Write(BinaryWriter writer, IList list) where T : IBindingsCache
+ {
+ if (list != null)
+ {
+ var count = list.Count;
+ writer.Write(count);
+ for (int i = 0; i < count; i++)
+ {
+ var e = list[i];
+ writer.Write(e.GetType().FullName);
+ e.Write(writer);
+ }
+ }
+ else
+ {
+ writer.Write(0);
+ }
+ }
+
+ internal static string Read(BinaryReader reader, string e)
+ {
+ var valid = reader.ReadBoolean();
+ if (valid)
+ e = reader.ReadString();
+ return e;
+ }
+
+ internal static string[] Read(BinaryReader reader, string[] list)
+ {
+ var count = reader.ReadInt32();
+ if (count != 0)
+ {
+ list = new string[count];
+ for (int i = 0; i < count; i++)
+ list[i] = reader.ReadString();
+ }
+ return list;
+ }
+
+ internal static T Read(BinaryReader reader, T e) where T : IBindingsCache
+ {
+ var typename = reader.ReadString();
+ if (string.IsNullOrEmpty(typename))
+ return e;
+ if (!_typeCache.TryGetValue(typename, out var type))
+ {
+ type = Builder.BuildTypes.FirstOrDefault(x => x.FullName == typename);
+ if (type == null)
+ {
+ var msg = $"Missing type {typename}.";
+ Log.Error(msg);
+ throw new Exception(msg);
+ }
+ _typeCache.Add(typename, type);
+ }
+ e = (T)Activator.CreateInstance(type);
+ e.Read(reader);
+ return e;
+ }
+
+ internal static List Read(BinaryReader reader, List list) where T : IBindingsCache
+ {
+ var count = reader.ReadInt32();
+ if (count != 0)
+ {
+ list = new List(count);
+ for (int i = 0; i < count; i++)
+ {
+ var typename = reader.ReadString();
+ if (!_typeCache.TryGetValue(typename, out var type))
+ {
+ type = Builder.BuildTypes.FirstOrDefault(x => x.FullName == typename);
+ if (type == null)
+ {
+ var msg = $"Missing type {typename}.";
+ Log.Error(msg);
+ throw new Exception(msg);
+ }
+ _typeCache.Add(typename, type);
+ }
+ var e = (T)Activator.CreateInstance(type);
+ e.Read(reader);
+ list.Add(e);
+ }
+ }
+ return list;
+ }
+
+ private static string GetCachePath(Module module, BuildOptions moduleOptions)
+ {
+ return Path.Combine(moduleOptions.IntermediateFolder, module.Name + ".Bindings.cache");
+ }
+
+ private static void SaveCache(ModuleInfo moduleInfo, BuildOptions moduleOptions, List headerFiles)
+ {
+ var path = GetCachePath(moduleInfo.Module, moduleOptions);
+ using (var stream = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read))
+ using (var writer = new BinaryWriter(stream, Encoding.UTF8))
+ {
+ // Version
+ writer.Write(4);
+ writer.Write(File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location).Ticks);
+
+ // Build options
+ writer.Write(moduleOptions.IntermediateFolder);
+ writer.Write((int)moduleOptions.Platform.Target);
+ writer.Write((int)moduleOptions.Architecture);
+ writer.Write((int)moduleOptions.Configuration);
+ Write(writer, moduleOptions.PublicDefinitions);
+ Write(writer, moduleOptions.PrivateDefinitions);
+ Write(writer, moduleOptions.CompileEnv.PreprocessorDefinitions);
+
+ // Header files
+ writer.Write(headerFiles.Count);
+ for (int i = 0; i < headerFiles.Count; i++)
+ {
+ var headerFile = headerFiles[i];
+ writer.Write(headerFile);
+ writer.Write(File.GetLastWriteTime(headerFile).Ticks);
+ }
+
+ // Info
+ moduleInfo.Write(writer);
+ }
+ }
+
+ private static bool LoadCache(ref ModuleInfo moduleInfo, BuildOptions moduleOptions, List headerFiles)
+ {
+ var path = GetCachePath(moduleInfo.Module, moduleOptions);
+ if (!File.Exists(path))
+ return false;
+ using (var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
+ using (var reader = new BinaryReader(stream, Encoding.UTF8))
+ {
+ // Version
+ var version = reader.ReadInt32();
+ if (version != 4)
+ return false;
+ if (File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location).Ticks != reader.ReadInt64())
+ return false;
+
+ // Build options
+ if (reader.ReadString() != moduleOptions.IntermediateFolder ||
+ reader.ReadInt32() != (int)moduleOptions.Platform.Target ||
+ reader.ReadInt32() != (int)moduleOptions.Architecture ||
+ reader.ReadInt32() != (int)moduleOptions.Configuration)
+ return false;
+ var publicDefinitions = Read(reader, Utilities.GetEmptyArray());
+ if (publicDefinitions.Length != moduleOptions.PublicDefinitions.Count || publicDefinitions.Any(x => !moduleOptions.PublicDefinitions.Contains(x)))
+ return false;
+ var privateDefinitions = Read(reader, Utilities.GetEmptyArray());
+ if (privateDefinitions.Length != moduleOptions.PrivateDefinitions.Count || privateDefinitions.Any(x => !moduleOptions.PrivateDefinitions.Contains(x)))
+ return false;
+ var preprocessorDefinitions = Read(reader, Utilities.GetEmptyArray());
+ if (preprocessorDefinitions.Length != moduleOptions.CompileEnv.PreprocessorDefinitions.Count || preprocessorDefinitions.Any(x => !moduleOptions.CompileEnv.PreprocessorDefinitions.Contains(x)))
+ return false;
+
+ // Header files
+ var headerFilesCount = reader.ReadInt32();
+ if (headerFilesCount != headerFiles.Count)
+ return false;
+ for (int i = 0; i < headerFilesCount; i++)
+ {
+ var headerFile = headerFiles[i];
+ if (headerFile != reader.ReadString())
+ return false;
+ if (File.GetLastWriteTime(headerFile).Ticks > reader.ReadInt64())
+ return false;
+ }
+
+ // Info
+ var newModuleInfo = new ModuleInfo
+ {
+ Module = moduleInfo.Module,
+ Name = moduleInfo.Name,
+ Namespace = moduleInfo.Namespace,
+ Children = new List(),
+ };
+ try
+ {
+ newModuleInfo.Read(reader);
+
+ // Skip parsing and use data loaded from cache
+ moduleInfo = newModuleInfo;
+ return true;
+ }
+ catch
+ {
+ // Skip loading cache
+ return false;
+ }
+ }
+ }
+ }
+}
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
index ff2a2fadd..d62a53144 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs
@@ -1091,7 +1091,7 @@ namespace Flax.Build.Bindings
{
if (!useScripting)
continue;
- var paramsCount = eventInfo.Type.GenericArgs.Count;
+ var paramsCount = eventInfo.Type.GenericArgs?.Count ?? 0;
// C# event invoking wrapper (calls C# event from C++ delegate)
CppIncludeFiles.Add("Engine/Scripting/ManagedCLR/MEvent.h");
@@ -1109,7 +1109,7 @@ namespace Flax.Build.Bindings
contents.Append(" {").AppendLine();
contents.Append(" static MMethod* mmethod = nullptr;").AppendLine();
contents.Append(" if (!mmethod)").AppendLine();
- contents.AppendFormat(" mmethod = {1}::GetStaticClass()->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, eventInfo.Type.GenericArgs.Count).AppendLine();
+ contents.AppendFormat(" mmethod = {1}::GetStaticClass()->GetMethod(\"Internal_{0}_Invoke\", {2});", eventInfo.Name, classTypeNameNative, paramsCount).AppendLine();
contents.Append(" CHECK(mmethod);").AppendLine();
contents.Append(" MonoObject* exception = nullptr;").AppendLine();
if (paramsCount == 0)
@@ -1174,7 +1174,7 @@ namespace Flax.Build.Bindings
if (paramsCount == 0)
contents.AppendLine(" Variant* params = nullptr;");
else
- contents.AppendLine($" Variant params[{eventInfo.Type.GenericArgs.Count}];");
+ contents.AppendLine($" Variant params[{paramsCount}];");
for (var i = 0; i < paramsCount; i++)
{
var paramType = eventInfo.Type.GenericArgs[i];
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
index 66f93fde3..7714e6abd 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Parsing.cs
@@ -475,13 +475,8 @@ namespace Flax.Build.Bindings
{
var desc = new ClassInfo
{
- Children = new List(),
Access = context.CurrentAccessLevel,
BaseTypeInheritance = AccessLevel.Private,
- Functions = new List(),
- Properties = new List(),
- Fields = new List(),
- Events = new List(),
};
// Read the documentation comment
@@ -559,7 +554,6 @@ namespace Flax.Build.Bindings
{
var desc = new InterfaceInfo
{
- Children = new List(),
Access = context.CurrentAccessLevel,
};
@@ -622,7 +616,6 @@ namespace Flax.Build.Bindings
var desc = new FunctionInfo
{
Access = context.CurrentAccessLevel,
- Parameters = new List(),
};
// Read the documentation comment
@@ -821,9 +814,7 @@ namespace Flax.Build.Bindings
{
var desc = new EnumInfo
{
- Children = new List(),
Access = context.CurrentAccessLevel,
- Entries = new List(),
};
// Read the documentation comment
@@ -978,10 +969,7 @@ namespace Flax.Build.Bindings
{
var desc = new StructureInfo
{
- Children = new List(),
Access = context.CurrentAccessLevel,
- Fields = new List(),
- Functions = new List(),
};
// Read the documentation comment
@@ -1200,7 +1188,6 @@ namespace Flax.Build.Bindings
context.Tokenizer.ExpectToken(TokenType.LeftParent);
var desc = new InjectCppCodeInfo
{
- Children = new List(),
Code = context.Tokenizer.ExpectToken(TokenType.String).Value.Replace("\\\"", "\""),
};
desc.Code = desc.Code.Substring(1, desc.Code.Length - 2);
diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs
index 1b12cb838..0135f1130 100644
--- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs
+++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.cs
@@ -100,6 +100,26 @@ namespace Flax.Build.Bindings
}
}
+ // Sort file paths to have stable results
+ headerFiles.Sort();
+
+ // Load cache
+ using (new ProfileEventScope("LoadCache"))
+ {
+ if (LoadCache(ref moduleInfo, moduleOptions, headerFiles))
+ {
+ buildData.ModulesInfo[module] = moduleInfo;
+
+ // Initialize API
+ using (new ProfileEventScope("Init"))
+ {
+ moduleInfo.Init(buildData);
+ }
+
+ return moduleInfo;
+ }
+ }
+
// Parse bindings
Log.Verbose($"Parsing API bindings for {module.Name} ({moduleInfo.Name})");
int concurrency = Math.Min(Math.Max(1, (int)(Environment.ProcessorCount * Configuration.ConcurrencyProcessorScale)), Configuration.MaxConcurrency);
@@ -117,9 +137,6 @@ namespace Flax.Build.Bindings
}
else
{
- // Sort by file size to improve performance (parse larger files first)
- headerFiles.Sort((a, b) => new System.IO.FileInfo(b).Length.CompareTo(new System.IO.FileInfo(a).Length));
-
// Multi-threaded
ThreadPool.GetMinThreads(out var workerThreads, out var completionPortThreads);
if (workerThreads != concurrency)
@@ -133,6 +150,12 @@ namespace Flax.Build.Bindings
});
}
+ // Save cache
+ using (new ProfileEventScope("SaveCache"))
+ {
+ SaveCache(moduleInfo, moduleOptions, headerFiles);
+ }
+
// Initialize API
using (new ProfileEventScope("Init"))
{
@@ -162,7 +185,6 @@ namespace Flax.Build.Bindings
var fileInfo = new FileInfo
{
Parent = null,
- Children = new List(),
Name = headerFiles[workIndex],
Namespace = moduleInfo.Name,
};
diff --git a/Source/Tools/Flax.Build/Bindings/ClassInfo.cs b/Source/Tools/Flax.Build/Bindings/ClassInfo.cs
index a83ac2b55..c68ff1a59 100644
--- a/Source/Tools/Flax.Build/Bindings/ClassInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/ClassInfo.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
+using System.IO;
using System.Linq;
namespace Flax.Build.Bindings
@@ -29,10 +30,10 @@ namespace Flax.Build.Bindings
public bool IsAutoSerialization;
public bool NoSpawn;
public bool NoConstructor;
- public List Functions;
- public List Properties;
- public List Fields;
- public List Events;
+ public List Functions = new List();
+ public List Properties = new List();
+ public List Fields = new List();
+ public List Events = new List();
internal HashSet UniqueFunctionNames;
@@ -74,6 +75,40 @@ namespace Flax.Build.Bindings
}
}
+ public override void Write(BinaryWriter writer)
+ {
+ // TODO: convert into flags
+ writer.Write(IsStatic);
+ writer.Write(IsSealed);
+ writer.Write(IsAbstract);
+ writer.Write(IsAutoSerialization);
+ writer.Write(NoSpawn);
+ writer.Write(NoConstructor);
+ BindingsGenerator.Write(writer, Functions);
+ BindingsGenerator.Write(writer, Properties);
+ BindingsGenerator.Write(writer, Fields);
+ BindingsGenerator.Write(writer, Events);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ // TODO: convert into flags
+ IsStatic = reader.ReadBoolean();
+ IsSealed = reader.ReadBoolean();
+ IsAbstract = reader.ReadBoolean();
+ IsAutoSerialization = reader.ReadBoolean();
+ NoSpawn = reader.ReadBoolean();
+ NoConstructor = reader.ReadBoolean();
+ Functions = BindingsGenerator.Read(reader, Functions);
+ Properties = BindingsGenerator.Read(reader, Properties);
+ Fields = BindingsGenerator.Read(reader, Fields);
+ Events = BindingsGenerator.Read(reader, Events);
+
+ base.Read(reader);
+ }
+
public int GetScriptVTableSize(Builder.BuildData buildData, out int offset)
{
if (_scriptVTableSize == -1)
diff --git a/Source/Tools/Flax.Build/Bindings/ClassStructInfo.cs b/Source/Tools/Flax.Build/Bindings/ClassStructInfo.cs
index dcb2d2e9e..2f0dad003 100644
--- a/Source/Tools/Flax.Build/Bindings/ClassStructInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/ClassStructInfo.cs
@@ -1,7 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
-using System;
using System.Collections.Generic;
+using System.IO;
namespace Flax.Build.Bindings
{
@@ -36,5 +36,25 @@ namespace Flax.Build.Bindings
Interfaces = null;
}
}
+
+ public override void Write(BinaryWriter writer)
+ {
+ writer.Write((byte)Access);
+ writer.Write((byte)BaseTypeInheritance);
+ BindingsGenerator.Write(writer, BaseType);
+ BindingsGenerator.Write(writer, InterfaceNames);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ Access = (AccessLevel)reader.ReadByte();
+ BaseTypeInheritance = (AccessLevel)reader.ReadByte();
+ BaseType = BindingsGenerator.Read(reader, BaseType);
+ InterfaceNames = BindingsGenerator.Read(reader, InterfaceNames);
+
+ base.Read(reader);
+ }
}
}
diff --git a/Source/Tools/Flax.Build/Bindings/EnumInfo.cs b/Source/Tools/Flax.Build/Bindings/EnumInfo.cs
index bf9fc8132..ddfcb3a38 100644
--- a/Source/Tools/Flax.Build/Bindings/EnumInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/EnumInfo.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
namespace Flax.Build.Bindings
{
@@ -10,7 +11,7 @@ namespace Flax.Build.Bindings
///
public class EnumInfo : ApiTypeInfo
{
- public struct EntryInfo
+ public struct EntryInfo : IBindingsCache
{
public string Name;
public string[] Comment;
@@ -21,11 +22,27 @@ namespace Flax.Build.Bindings
{
return Name + (string.IsNullOrEmpty(Value) ? string.Empty : " = " + Value);
}
+
+ public void Write(BinaryWriter writer)
+ {
+ writer.Write(Name);
+ BindingsGenerator.Write(writer, Comment);
+ BindingsGenerator.Write(writer, Value);
+ BindingsGenerator.Write(writer, Attributes);
+ }
+
+ public void Read(BinaryReader reader)
+ {
+ Name = reader.ReadString();
+ Comment = BindingsGenerator.Read(reader, Comment);
+ Value = BindingsGenerator.Read(reader, Value);
+ Attributes = BindingsGenerator.Read(reader, Attributes);
+ }
}
public AccessLevel Access;
public TypeInfo UnderlyingType;
- public List Entries;
+ public List Entries = new List();
public override bool IsValueType => true;
public override bool IsEnum => true;
@@ -36,6 +53,24 @@ namespace Flax.Build.Bindings
throw new NotSupportedException("API enums cannot have sub-types.");
}
+ public override void Write(BinaryWriter writer)
+ {
+ writer.Write((byte)Access);
+ BindingsGenerator.Write(writer, UnderlyingType);
+ BindingsGenerator.Write(writer, Entries);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ Access = (AccessLevel)reader.ReadByte();
+ UnderlyingType = BindingsGenerator.Read(reader, UnderlyingType);
+ Entries = BindingsGenerator.Read(reader, Entries);
+
+ base.Read(reader);
+ }
+
public override string ToString()
{
return "enum " + Name;
diff --git a/Source/Tools/Flax.Build/Bindings/EventInfo.cs b/Source/Tools/Flax.Build/Bindings/EventInfo.cs
index de93332ac..905bee803 100644
--- a/Source/Tools/Flax.Build/Bindings/EventInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/EventInfo.cs
@@ -1,5 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+using System.IO;
+
namespace Flax.Build.Bindings
{
///
@@ -9,6 +11,20 @@ namespace Flax.Build.Bindings
{
public TypeInfo Type;
+ public override void Write(BinaryWriter writer)
+ {
+ BindingsGenerator.Write(writer, Type);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ Type = BindingsGenerator.Read(reader, Type);
+
+ base.Read(reader);
+ }
+
public override string ToString()
{
var result = string.Empty;
diff --git a/Source/Tools/Flax.Build/Bindings/FieldInfo.cs b/Source/Tools/Flax.Build/Bindings/FieldInfo.cs
index b1488ed09..d01cde5e7 100644
--- a/Source/Tools/Flax.Build/Bindings/FieldInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/FieldInfo.cs
@@ -1,5 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+using System.IO;
+
namespace Flax.Build.Bindings
{
///
@@ -16,6 +18,28 @@ namespace Flax.Build.Bindings
public bool HasDefaultValue => !string.IsNullOrEmpty(DefaultValue);
+ public override void Write(BinaryWriter writer)
+ {
+ BindingsGenerator.Write(writer, Type);
+ // TODO: convert into flags
+ writer.Write(IsReadOnly);
+ writer.Write(NoArray);
+ BindingsGenerator.Write(writer, DefaultValue);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ Type = BindingsGenerator.Read(reader, Type);
+ // TODO: convert into flags
+ IsReadOnly = reader.ReadBoolean();
+ NoArray = reader.ReadBoolean();
+ DefaultValue = BindingsGenerator.Read(reader, DefaultValue);
+
+ base.Read(reader);
+ }
+
public override string ToString()
{
var result = string.Empty;
diff --git a/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs b/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs
index 953fd7ed4..a78c9242a 100644
--- a/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/FunctionInfo.cs
@@ -1,6 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System.Collections.Generic;
+using System.IO;
namespace Flax.Build.Bindings
{
@@ -9,7 +10,7 @@ namespace Flax.Build.Bindings
///
public class FunctionInfo : MemberInfo
{
- public struct ParameterInfo
+ public struct ParameterInfo : IBindingsCache
{
public string Name;
public TypeInfo Type;
@@ -25,6 +26,28 @@ namespace Flax.Build.Bindings
return Attributes != null && Attributes.Contains(name);
}
+ public void Write(BinaryWriter writer)
+ {
+ writer.Write(Name);
+ BindingsGenerator.Write(writer, Type);
+ BindingsGenerator.Write(writer, DefaultValue);
+ BindingsGenerator.Write(writer, Attributes);
+ // TODO: convert into flags
+ writer.Write(IsRef);
+ writer.Write(IsOut);
+ }
+
+ public void Read(BinaryReader reader)
+ {
+ Name = reader.ReadString();
+ Type = BindingsGenerator.Read(reader, Type);
+ DefaultValue = BindingsGenerator.Read(reader, DefaultValue);
+ Attributes = BindingsGenerator.Read(reader, Attributes);
+ // TODO: convert into flags
+ IsRef = reader.ReadBoolean();
+ IsOut = reader.ReadBoolean();
+ }
+
public override string ToString()
{
var result = Type + " " + Name;
@@ -42,12 +65,36 @@ namespace Flax.Build.Bindings
public string UniqueName;
public TypeInfo ReturnType;
- public List Parameters;
+ public List Parameters = new List();
public bool IsVirtual;
public bool IsConst;
public bool NoProxy;
public GlueInfo Glue;
+ public override void Write(BinaryWriter writer)
+ {
+ BindingsGenerator.Write(writer, ReturnType);
+ BindingsGenerator.Write(writer, Parameters);
+ // TODO: convert into flags
+ writer.Write(IsVirtual);
+ writer.Write(IsConst);
+ writer.Write(NoProxy);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ ReturnType = BindingsGenerator.Read(reader, ReturnType);
+ Parameters = BindingsGenerator.Read(reader, Parameters);
+ // TODO: convert into flags
+ IsVirtual = reader.ReadBoolean();
+ IsConst = reader.ReadBoolean();
+ NoProxy = reader.ReadBoolean();
+
+ base.Read(reader);
+ }
+
public override string ToString()
{
var result = string.Empty;
diff --git a/Source/Tools/Flax.Build/Bindings/InjectCppCodeInfo.cs b/Source/Tools/Flax.Build/Bindings/InjectCppCodeInfo.cs
index dfdb551f6..0bb53fc99 100644
--- a/Source/Tools/Flax.Build/Bindings/InjectCppCodeInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/InjectCppCodeInfo.cs
@@ -1,5 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+using System.IO;
+
namespace Flax.Build.Bindings
{
///
@@ -9,6 +11,20 @@ namespace Flax.Build.Bindings
{
public string Code;
+ public override void Write(BinaryWriter writer)
+ {
+ writer.Write(Code);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ Code = reader.ReadString();
+
+ base.Read(reader);
+ }
+
///
public override string ToString()
{
diff --git a/Source/Tools/Flax.Build/Bindings/MemberInfo.cs b/Source/Tools/Flax.Build/Bindings/MemberInfo.cs
index 3e09b9f0b..49187c101 100644
--- a/Source/Tools/Flax.Build/Bindings/MemberInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/MemberInfo.cs
@@ -1,11 +1,13 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+using System.IO;
+
namespace Flax.Build.Bindings
{
///
/// The native member information for bindings generator.
///
- public class MemberInfo
+ public class MemberInfo : IBindingsCache
{
public string Name;
public string[] Comment;
@@ -17,5 +19,23 @@ namespace Flax.Build.Bindings
{
return Attributes != null && Attributes.Contains(name);
}
+
+ public virtual void Write(BinaryWriter writer)
+ {
+ writer.Write(Name);
+ BindingsGenerator.Write(writer, Comment);
+ writer.Write(IsStatic);
+ writer.Write((byte)Access);
+ BindingsGenerator.Write(writer, Attributes);
+ }
+
+ public virtual void Read(BinaryReader reader)
+ {
+ Name = reader.ReadString();
+ Comment = BindingsGenerator.Read(reader, Comment);
+ IsStatic = reader.ReadBoolean();
+ Access = (AccessLevel)reader.ReadByte();
+ Attributes = BindingsGenerator.Read(reader, Attributes);
+ }
}
}
diff --git a/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs b/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs
index 7bb6d1608..dd83af9d9 100644
--- a/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/ModuleInfo.cs
@@ -1,5 +1,8 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+using System;
+using System.IO;
+
namespace Flax.Build.Bindings
{
///
@@ -22,5 +25,26 @@ namespace Flax.Build.Bindings
// Sort module files to prevent bindings rebuild due to order changes (list might be created in async)
Children.Sort();
}
+
+ public override void Write(BinaryWriter writer)
+ {
+ writer.Write(Module.Name);
+ writer.Write(Module.FilePath);
+ BindingsGenerator.Write(writer, Module.BinaryModuleName);
+ writer.Write(Module.BuildNativeCode);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ if (reader.ReadString() != Module.Name ||
+ reader.ReadString() != Module.FilePath ||
+ BindingsGenerator.Read(reader, Module.BinaryModuleName) != Module.BinaryModuleName ||
+ reader.ReadBoolean() != Module.BuildNativeCode)
+ throw new Exception();
+
+ base.Read(reader);
+ }
}
}
diff --git a/Source/Tools/Flax.Build/Bindings/PropertyInfo.cs b/Source/Tools/Flax.Build/Bindings/PropertyInfo.cs
index f53578b4e..96b0f8b93 100644
--- a/Source/Tools/Flax.Build/Bindings/PropertyInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/PropertyInfo.cs
@@ -1,5 +1,7 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
+using System.IO;
+
namespace Flax.Build.Bindings
{
///
@@ -11,6 +13,24 @@ namespace Flax.Build.Bindings
public FunctionInfo Getter;
public FunctionInfo Setter;
+ public override void Write(BinaryWriter writer)
+ {
+ BindingsGenerator.Write(writer, Type);
+ BindingsGenerator.Write(writer, Getter);
+ BindingsGenerator.Write(writer, Setter);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ Type = BindingsGenerator.Read(reader, Type);
+ Getter = BindingsGenerator.Read(reader, Getter);
+ Setter = BindingsGenerator.Read(reader, Setter);
+
+ base.Read(reader);
+ }
+
public override string ToString()
{
return Type + " " + Name;
diff --git a/Source/Tools/Flax.Build/Bindings/StructureInfo.cs b/Source/Tools/Flax.Build/Bindings/StructureInfo.cs
index be24bb1f0..882ed6295 100644
--- a/Source/Tools/Flax.Build/Bindings/StructureInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/StructureInfo.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
namespace Flax.Build.Bindings
{
@@ -10,8 +11,8 @@ namespace Flax.Build.Bindings
///
public class StructureInfo : ClassStructInfo
{
- public List Fields;
- public List Functions;
+ public List Fields = new List();
+ public List Functions = new List();
public bool IsAutoSerialization;
public bool ForceNoPod;
@@ -43,6 +44,26 @@ namespace Flax.Build.Bindings
}
}
+ public override void Write(BinaryWriter writer)
+ {
+ BindingsGenerator.Write(writer, Fields);
+ BindingsGenerator.Write(writer, Functions);
+ writer.Write(IsAutoSerialization);
+ writer.Write(ForceNoPod);
+
+ base.Write(writer);
+ }
+
+ public override void Read(BinaryReader reader)
+ {
+ Fields = BindingsGenerator.Read(reader, Fields);
+ Functions = BindingsGenerator.Read(reader, Functions);
+ IsAutoSerialization = reader.ReadBoolean();
+ ForceNoPod = reader.ReadBoolean();
+
+ base.Read(reader);
+ }
+
public override void AddChild(ApiTypeInfo apiTypeInfo)
{
if (apiTypeInfo is EnumInfo)
diff --git a/Source/Tools/Flax.Build/Bindings/TypeInfo.cs b/Source/Tools/Flax.Build/Bindings/TypeInfo.cs
index f2d7ff387..2d15f6651 100644
--- a/Source/Tools/Flax.Build/Bindings/TypeInfo.cs
+++ b/Source/Tools/Flax.Build/Bindings/TypeInfo.cs
@@ -2,6 +2,7 @@
using System;
using System.Collections.Generic;
+using System.IO;
using System.Linq;
using System.Text;
@@ -10,7 +11,7 @@ namespace Flax.Build.Bindings
///
/// The native type information for bindings generator.
///
- public class TypeInfo : IEquatable
+ public class TypeInfo : IEquatable, IBindingsCache
{
public string Type;
public bool IsConst;
@@ -51,6 +52,34 @@ namespace Flax.Build.Bindings
return true;
}
+ public void Write(BinaryWriter writer)
+ {
+ BindingsGenerator.Write(writer, Type);
+ // TODO: pack as flags
+ writer.Write(IsConst);
+ writer.Write(IsRef);
+ writer.Write(IsPtr);
+ writer.Write(IsArray);
+ writer.Write(IsBitField);
+ writer.Write(ArraySize);
+ writer.Write(BitSize);
+ BindingsGenerator.Write(writer, GenericArgs);
+ }
+
+ public void Read(BinaryReader reader)
+ {
+ Type = BindingsGenerator.Read(reader, Type);
+ // TODO: convert into flags
+ IsConst = reader.ReadBoolean();
+ IsRef = reader.ReadBoolean();
+ IsPtr = reader.ReadBoolean();
+ IsArray = reader.ReadBoolean();
+ IsBitField = reader.ReadBoolean();
+ ArraySize = reader.ReadInt32();
+ BitSize = reader.ReadInt32();
+ GenericArgs = BindingsGenerator.Read(reader, GenericArgs);
+ }
+
public override string ToString()
{
var sb = new StringBuilder(64);
diff --git a/Source/Tools/Flax.Build/Flax.Build.csproj b/Source/Tools/Flax.Build/Flax.Build.csproj
index 9d415beed..236348032 100644
--- a/Source/Tools/Flax.Build/Flax.Build.csproj
+++ b/Source/Tools/Flax.Build/Flax.Build.csproj
@@ -64,6 +64,7 @@
+
diff --git a/Source/Tools/Flax.Build/Utilities/Utilities.cs b/Source/Tools/Flax.Build/Utilities/Utilities.cs
index c37faa678..accf86209 100644
--- a/Source/Tools/Flax.Build/Utilities/Utilities.cs
+++ b/Source/Tools/Flax.Build/Utilities/Utilities.cs
@@ -14,6 +14,16 @@ namespace Flax.Build
///
public static class Utilities
{
+ ///
+ /// Gets the empty array of the given type (shared one).
+ ///
+ /// The type.
+ /// The empty array object.
+ public static T[] GetEmptyArray()
+ {
+ return Enumerable.Empty() as T[];
+ }
+
///
/// Gets the size of the file as a readable string.
///