copygirl 1 year ago
parent 46e171940e
commit 58d0502ff2
  1. 3
      .gitmodules
  2. 17
      .vscode/launch.json
  3. 8
      .vscode/settings.json
  4. 18
      .vscode/tasks.json
  5. 2
      README.md
  6. 3943
      flecs.g.cs
  7. 14548
      flecs.h-ast
  8. 34
      gaemstone.ECS.sln
  9. 1
      src/flecs
  10. 272
      src/gaemstone.ECS.BindGen/Program.cs
  11. 12
      src/gaemstone.ECS.BindGen/gaemstone.ECS.BindGen.csproj
  12. 2
      src/gaemstone.ECS/EntityBuilder.cs
  13. 2
      src/gaemstone.ECS/EntityPath.cs
  14. 2
      src/gaemstone.ECS/EntityRef.cs
  15. 2
      src/gaemstone.ECS/EntityType.cs
  16. 2
      src/gaemstone.ECS/Filter.cs
  17. 2
      src/gaemstone.ECS/IdRef.cs
  18. 2
      src/gaemstone.ECS/Iterator.cs
  19. 2
      src/gaemstone.ECS/Observer.cs
  20. 2
      src/gaemstone.ECS/Query.cs
  21. 2
      src/gaemstone.ECS/Rule.cs
  22. 2
      src/gaemstone.ECS/System.cs
  23. 2
      src/gaemstone.ECS/Term.cs
  24. 2
      src/gaemstone.ECS/Utility/Allocators.cs
  25. 4
      src/gaemstone.ECS/Utility/CStringExtensions.cs
  26. 2
      src/gaemstone.ECS/Utility/CallbackContextHelper.cs
  27. 2
      src/gaemstone.ECS/Utility/FlecsException.cs
  28. 2
      src/gaemstone.ECS/Utility/SpanExtensions.cs
  29. 2
      src/gaemstone.ECS/World+Lookup.cs
  30. 2
      src/gaemstone.ECS/World.cs
  31. 14
      src/gaemstone.ECS/gaemstone.ECS.csproj

3
.gitmodules vendored

@ -1,3 +1,6 @@
[submodule "src/flecs-cs"]
path = src/flecs-cs
url = https://github.com/flecs-hub/flecs-cs
[submodule "src/flecs"]
path = src/flecs
url = https://github.com/SanderMertens/flecs.git

@ -0,0 +1,17 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch BindGen",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"env": { "LIBCLANG_DISABLE_CRASH_RECOVERY": "true" },
"program": "${workspaceFolder}/src/gaemstone.ECS.BindGen/bin/Debug/net7.0/gaemstone.ECS.BindGen.dll",
"args": [],
"cwd": "${workspaceFolder}/src/gaemstone.ECS.BindGen",
"console": "internalConsole",
"stopAtEntry": false,
}
]
}

@ -0,0 +1,8 @@
{
"files.exclude": {
"**/.git": true,
"**/.DS_Store": true,
"**/bin": true,
"**/obj": true,
}
}

18
.vscode/tasks.json vendored

@ -0,0 +1,18 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"build",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"group": "build",
"presentation": { "reveal": "silent" },
"problemMatcher": "$msCompile"
}
]
}

@ -104,7 +104,7 @@ git clone --recurse-submodules https://git.mcft.net/copygirl/gaemstone.ECS.git
git submodule add https://git.mcft.net/copygirl/gaemstone.ECS.git
# To add a reference to this library to your .NET project:
dotnet add reference gaemstone.ECS/gaemstone.ECS.csproj
dotnet add reference gaemstone.ECS/src/gaemstone.ECS/gaemstone.ECS.csproj
# To generate flecs-cs' bindings:
./gaemstone.ECS/src/flecs-cs/library.sh

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{0FC51081-529F-4DC2-91D0-18002C10B733}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaemstone.ECS", "src\gaemstone.ECS\gaemstone.ECS.csproj", "{7CDAB372-16EB-452C-B984-0BD5F1D0D411}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gaemstone.ECS.BindGen", "src\gaemstone.ECS.BindGen\gaemstone.ECS.BindGen.csproj", "{4DA4F739-1C38-41D3-804B-B1114090FF53}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7CDAB372-16EB-452C-B984-0BD5F1D0D411}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CDAB372-16EB-452C-B984-0BD5F1D0D411}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CDAB372-16EB-452C-B984-0BD5F1D0D411}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CDAB372-16EB-452C-B984-0BD5F1D0D411}.Release|Any CPU.Build.0 = Release|Any CPU
{4DA4F739-1C38-41D3-804B-B1114090FF53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4DA4F739-1C38-41D3-804B-B1114090FF53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4DA4F739-1C38-41D3-804B-B1114090FF53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4DA4F739-1C38-41D3-804B-B1114090FF53}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{7CDAB372-16EB-452C-B984-0BD5F1D0D411} = {0FC51081-529F-4DC2-91D0-18002C10B733}
{4DA4F739-1C38-41D3-804B-B1114090FF53} = {0FC51081-529F-4DC2-91D0-18002C10B733}
EndGlobalSection
EndGlobal

@ -0,0 +1 @@
Subproject commit ddf4dfc8d0b09eec42876ea06f5f42849a0c23be

@ -0,0 +1,272 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using ClangSharp.Interop;
namespace gaemstone.ECS.BindGen;
public unsafe static class Program
{
private const string FlecsHeaderFileLocation = "../flecs/flecs.h";
private const string OutputFolderLocation = "../..";
public static void Main()
{
var output = new StringBuilder();
output.AppendLine("""
// <auto-generated/>
using System.Runtime.InteropServices; // For use with unions.
#pragma warning disable CS8981
public static unsafe partial class flecs
{
""");
var args = new string[] {
// "-fparse-all-comments",
"--comments-in-macros",
"--comments",
};
using var index = CXIndex.Create();
using var unit = CXTranslationUnit.CreateFromSourceFile(index, FlecsHeaderFileLocation, args, default);
unit.Cursor.VisitChildren((cursor, _, _) => {
switch (cursor) {
case { Location.IsFromMainFile: false }:
// Not from the file we're trying to parse.
break;
case { Kind: CXCursorKind.CXCursor_MacroInstantiation
or CXCursorKind.CXCursor_InclusionDirective }:
// Ignore these altogether.
break;
case { Kind: CXCursorKind.CXCursor_MacroDefinition }:
WriteMacro(cursor, output);
break;
// case { Kind: CXCursorKind.CXCursor_TypedefDecl }:
// WriteTypedef(cursor, output);
// break;
case { Kind: CXCursorKind.CXCursor_StructDecl }:
WriteStruct(cursor, output);
break;
case { Kind: CXCursorKind.CXCursor_FunctionDecl }:
WriteFunction(cursor, output);
break;
default:
Console.WriteLine($"{cursor.Kind} {cursor}");
Console.WriteLine(GetSource(unit, cursor.Extent));
break;
}
return CXChildVisitResult.CXChildVisit_Continue;
}, default);
output.AppendLine("""
}
""");
File.WriteAllText(Path.Combine(OutputFolderLocation, "flecs.g.cs"), output.ToString());
}
private static void WriteMacro(CXCursor cursor, StringBuilder output, int indent = 1)
{
if (cursor.IsMacroFunctionLike) return;
var unit = cursor.TranslationUnit;
var tokens = unit.Tokenize(cursor.Extent).ToArray();
if (tokens.Length < 2) return; // No value.
var name = cursor.Spelling.ToString();
if (name is "NULL" or "ECS_VECTOR_T_SIZE"
or "EcsLastInternalComponentId" or "ECS_FUNC_NAME_BACK") return;
var type = "uint";
var value = GetSource(unit, Range(unit, tokens[1], tokens[^1]));
if (value is not [ '(', .., ')']) return;
if (value.Contains('\\')) value = value.Replace("\\\n", "").Replace(" ", "");
if (value.Contains("ull")) { value = value.Replace("ull", "ul"); type = "ulong"; }
// if (value.Contains("|") || value.Contains("<<")) type = "ulong";
if (name == "ECS_MAX_COMPONENT_ID") value.Replace("(uint32_t)", "(uint)");
WriteComment(cursor, output, indent);
output.Append('\t', indent).AppendLine($"public const {type} {name} = {value};");
}
private static void WriteStruct(CXCursor cursor, StringBuilder output,
int indent = 1, string? name = null, bool noComment = false)
{
// Skip forward declarations, unless they're not defined at all.
if (!cursor.IsDefinition && !cursor.Definition.IsNull) return;
if (!noComment) WriteComment(cursor, output, indent);
if (cursor.Kind == CXCursorKind.CXCursor_UnionDecl)
output.Append('\t', indent).AppendLine("[StructLayout(LayoutKind.Explicit)]");
name ??= cursor.Type.Declaration.ToString();
output.Append('\t', indent).Append("public struct ").Append(name);
if (name == "") throw new Exception();
var hasFields = false; // For creating a shorthand struct definition that doesn't take up 3 lines.
cursor.VisitChildren((field, _, _) => {
switch (field) {
case { IsAnonymous: true }:
// Anonymous struct and union declarations
// will be handled when field is written.
break;
case { Kind: CXCursorKind.CXCursor_FieldDecl
or CXCursorKind.CXCursor_StructDecl }:
if (!hasFields) {
output.AppendLine();
output.Append('\t', indent).AppendLine("{");
hasFields = true;
}
if (cursor.Kind == CXCursorKind.CXCursor_UnionDecl)
output.Append('\t', indent + 1).AppendLine("[FieldOffset(0)]");
WriteComment(field, output, indent + 1);
output.Append('\t', indent + 1).Append("public ");
var name = field.DisplayName;
if (field.Type.Declaration.IsAnonymous) {
output.AppendLine($"_{name} {name};");
WriteStruct(field.Type.Declaration, output, indent + 1,
name: $"_{name}", noComment: true);
} else if (field.Type.kind == CXTypeKind.CXType_ConstantArray) {
output.AppendLine($"fixed {field.Type.ArrayElementType} {name}[{field.Type.ArraySize}];");
} else {
WriteType(field.Type, output);
output.AppendLine($" {name};");
}
break;
default:
throw new NotSupportedException();
}
return CXChildVisitResult.CXChildVisit_Continue;
}, default);
if (!hasFields) output.AppendLine(" { }");
else output.Append('\t', indent).AppendLine("}");
}
private static void WriteFunction(CXCursor cursor, StringBuilder output, int indent = 1)
{
WriteComment(cursor, output, indent);
output.Append('\t', indent).Append($"public static ");
WriteType(cursor.ReturnType, output);
output.Append($" {cursor.Spelling}(");
for (var i = 0; i < cursor.NumArguments; i++) {
var arg = cursor.GetArgument((uint)i);
if (i > 0) output.Append(", ");
WriteType(arg.Type, output);
output.Append($" {arg.DisplayName}");
}
output.AppendLine(");");
}
private static void WriteComment(CXCursor cursor, StringBuilder output, int indent)
{
var comment = cursor.ParsedComment;
if (comment.Kind == CXCommentKind.CXComment_Null) return;
Ensure(comment, CXCommentKind.CXComment_FullComment);
foreach (var child in Children(comment))
switch (child.Kind) {
case CXCommentKind.CXComment_Paragraph:
if (GetText(child) is string text)
output.Append('\t', indent).AppendLine($"/// <summary> {text} </summary>");
break;
case CXCommentKind.CXComment_ParamCommand:
var paramName = child.ParamCommandComment_ParamName;
var paramComment = GetText(Children(child).Single());
output.Append('\t', indent).AppendLine($$"""/// <param name="{{ paramName }}"> {{ paramComment }} </param>""");
break;
// case CXCommentKind.CXComment_BlockCommand:
// break;
default:
output.Append('\t', indent).AppendLine($"//// {child.Kind}");
break;
}
static CXComment Ensure(CXComment comment, CXCommentKind expected)
{ if (comment.Kind != expected) throw new NotSupportedException(); return comment; }
static IEnumerable<CXComment> Children(CXComment parent)
=> Enumerable.Range(0, (int)parent.NumChildren).Select(i => parent.GetChild((uint)i));
static string? GetText(CXComment paragraph)
{
Ensure(paragraph, CXCommentKind.CXComment_Paragraph);
var parts = Children(paragraph)
.Select(c => Ensure(c, CXCommentKind.CXComment_Text))
.Select(c => c.TextComment_Text.ToString().Trim())
.Where (s => s != string.Empty)
.Select(s => s.Replace("<", "&lt;").Replace(">", "&gt;"))
.ToArray();
return (parts.Length > 0) ? string.Join(" ", parts) : null;
}
}
private static void WriteType(CXType type, StringBuilder output)
{
// FIXME: Handle reserved keywords.
string name;
switch (type) {
case { kind: CXTypeKind.CXType_Pointer }:
WriteType(type.PointeeType, output);
output.Append('*');
break;
case { kind: CXTypeKind.CXType_VariableArray
or CXTypeKind.CXType_IncompleteArray }:
WriteType(type.ArrayElementType, output);
output.Append("[]");
break;
case { kind: CXTypeKind.CXType_Record }:
case { kind: CXTypeKind.CXType_Elaborated }:
name = type.Declaration.Spelling.ToString();
if (name == "") throw new Exception();
output.Append(name);
break;
case { kind: CXTypeKind.CXType_FunctionProto }:
// TODO: Handle this somehow?
name = type.Spelling.ToString();
output.Append(name);
break;
default:
name = type.Spelling.ToString();
if (name == "") throw new Exception();
if (type.IsConstQualified) {
// TODO: Do something with const-ness?
if (!name.StartsWith("const ")) throw new Exception();
name = name[("const ".Length)..];
}
if (name.Contains(' ')) throw new Exception();
output.Append(name);
break;
}
}
private static CXSourceRange Range(CXTranslationUnit unit, CXToken start, CXToken end)
=> CXSourceRange.Create(start.GetExtent(unit).Start, end.GetExtent(unit).End);
private static string GetSource(CXTranslationUnit unit, CXSourceRange range)
{
range.Start.GetFileLocation(out var startFile, out _, out _, out var start);
range.End .GetFileLocation(out var endFile , out _, out _, out var end);
if (startFile != endFile) return string.Empty;
return Encoding.UTF8.GetString(
unit.GetFileContents(startFile, out _)
.Slice((int)start, (int)(end - start)));
}
}

@ -1,6 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<LangVersion>preview</LangVersion>
<TargetFramework>net7.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ImplicitUsings>disable</ImplicitUsings>
@ -8,16 +10,12 @@
</PropertyGroup>
<PropertyGroup>
<EnableDefaultItems>false</EnableDefaultItems>
<RuntimeIdentifier>ubuntu.22.04-x64</RuntimeIdentifier>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="src/gaemstone.ECS/**/*.cs" />
<Compile Include="src/gaemstone.Utility/**/*.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="src/flecs-cs/src/cs/production/Flecs/Flecs.csproj" />
<PackageReference Include="ClangSharp" Version="15.0.2" />
</ItemGroup>
</Project>

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -2,7 +2,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,6 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,5 +1,5 @@
using System;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -2,7 +2,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,6 +1,6 @@
using System;
using System.Runtime.InteropServices;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,5 +1,5 @@
using System;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,7 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,6 +1,6 @@
using System;
using System.Runtime.InteropServices;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,5 +1,5 @@
using System;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -5,7 +5,7 @@ using System.Text;
using System.Threading;
using static flecs_hub.flecs.Runtime;
namespace gaemstone.Utility;
namespace gaemstone.ECS.Utility;
public interface IAllocator
{

@ -3,12 +3,12 @@ using System.Runtime.InteropServices;
using static flecs_hub.flecs;
using static flecs_hub.flecs.Runtime;
namespace gaemstone.Utility;
namespace gaemstone.ECS.Utility;
public unsafe static class CStringExtensions
{
public static CString Empty { get; } = (CString)"";
public static CString ETX { get; } = (CString)"\x3"; // TODO: Temporary, until flecs supports Empty.
public static CString ETX { get; } = (CString)"\x3"; // FIXME: Temporary, until flecs supports Empty.
public static unsafe byte[]? FlecsToBytes(this CString str)
{

@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace gaemstone.Utility;
namespace gaemstone.ECS.Utility;
public static class CallbackContextHelper
{

@ -2,7 +2,7 @@ using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace gaemstone.Utility;
namespace gaemstone.ECS.Utility;
public class FlecsException
: Exception

@ -1,6 +1,6 @@
using System;
namespace gaemstone.Utility;
namespace gaemstone.ECS.Utility;
public static class SpanExtensions
{

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -1,5 +1,5 @@
using System;
using gaemstone.Utility;
using gaemstone.ECS.Utility;
using static flecs_hub.flecs;
namespace gaemstone.ECS;

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ImplicitUsings>disable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="../flecs-cs/src/cs/production/Flecs/Flecs.csproj" />
</ItemGroup>
</Project>
Loading…
Cancel
Save