Skip to content

Commit

Permalink
[Native] Add generator for c# types used on c++ side
Browse files Browse the repository at this point in the history
  • Loading branch information
harry-cpp committed Feb 21, 2024
1 parent 7dc8aa0 commit 0cf7078
Show file tree
Hide file tree
Showing 5 changed files with 2,240 additions and 0 deletions.
11 changes: 11 additions & 0 deletions MonoGame.Framework.Native.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Framework.Native", "MonoGame.Framework\MonoGame.Framework.Native.csproj", "{56BA741D-6AF1-489B-AB00-338DE11B1D32}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{65B3DC17-24BA-4C39-810F-E371AC48199A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoGame.Generator.CTypes", "Tools\MonoGame.Generator.CTypes\MonoGame.Generator.CTypes.csproj", "{74F12E34-D96B-4EC1-A218-BAFC83DC6220}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -18,5 +22,12 @@ Global
{56BA741D-6AF1-489B-AB00-338DE11B1D32}.Debug|Any CPU.Build.0 = Debug|Any CPU
{56BA741D-6AF1-489B-AB00-338DE11B1D32}.Release|Any CPU.ActiveCfg = Release|Any CPU
{56BA741D-6AF1-489B-AB00-338DE11B1D32}.Release|Any CPU.Build.0 = Release|Any CPU
{74F12E34-D96B-4EC1-A218-BAFC83DC6220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{74F12E34-D96B-4EC1-A218-BAFC83DC6220}.Debug|Any CPU.Build.0 = Debug|Any CPU
{74F12E34-D96B-4EC1-A218-BAFC83DC6220}.Release|Any CPU.ActiveCfg = Release|Any CPU
{74F12E34-D96B-4EC1-A218-BAFC83DC6220}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{74F12E34-D96B-4EC1-A218-BAFC83DC6220} = {65B3DC17-24BA-4C39-810F-E371AC48199A}
EndGlobalSection
EndGlobal
10 changes: 10 additions & 0 deletions Tools/MonoGame.Generator.CTypes/MonoGame.Generator.CTypes.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
104 changes: 104 additions & 0 deletions Tools/MonoGame.Generator.CTypes/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System.Reflection;
using System.Text;

static string GetCEnumType(string cstype)
{
return cstype switch
{
"System.Byte" => "csbyte",
"System.Int16" => "csshort",
"System.UInt16" => "csushort",
"System.Int32" => "csint",
"System.UInt32" => "csuint",
"System.Int64" => "cslong",
"System.UInt64" => "csulong",
_ => "CS" + cstype
};
};

var repoDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../../../");
var monogamePlatformDir = Path.Combine(repoDirectory, "src/monogame/include");
var monogameFrameworkPath = Path.Combine(repoDirectory, "Artifacts/MonoGame.Framework/Native/Debug/MonoGame.Framework.dll");
var assembly = Assembly.LoadFile(monogameFrameworkPath);
var outputText = new StringBuilder();
var duplicateChecker = new Dictionary<string, string>();

outputText.AppendLine($"""
//
// This code is auto generated, don't modify it by hand.
// To regenerate it run: Tools/MonoGame.Generator.CTypes
//
#pragma once
#include "csharp_common.h"
""");

foreach (var enumType in assembly.GetTypes())
{
if (!enumType.IsEnum)
continue;

if (enumType.IsNested)
continue;

if (!enumType.FullName!.StartsWith("MonoGame") && !enumType.FullName!.StartsWith("Microsoft.Xna.Framework"))
continue;

if (duplicateChecker.TryGetValue(enumType.Name, out string? dupFullName))
{
Console.WriteLine($"""
WARNING: Duplicate enum name for {enumType.Name}:
- {enumType.FullName}
- {dupFullName}
""");
continue;
}

var enumValues = Enum.GetValues(enumType);

// Write all values to output
outputText.AppendLine($$"""
enum CS{{enumType.Name}} : {{GetCEnumType(Enum.GetUnderlyingType(enumType).ToString())}}
{
""");
foreach (var enumValue in enumValues)
{
outputText.AppendLine($" {enumValue} = {((Enum)enumValue).ToString("d")},");
}
outputText.AppendLine("""
};
""");

outputText.AppendLine($$"""
class ECS{{enumType.Name}}
{
public:
static const char* ToString(CS{{enumType.Name}} enumValue)
{
switch (enumValue)
{
""");
foreach (var enumValue in enumValues)
{
outputText.AppendLine($" case {enumValue}: return \"{enumValue}\";");
}
outputText.AppendLine("""
}
return "Unknown Value";
}
};
""");

duplicateChecker.Add(enumType.Name, enumType.FullName!);
}

if (!Directory.Exists(monogamePlatformDir))
Directory.CreateDirectory(monogamePlatformDir);

File.WriteAllText(Path.Combine(monogamePlatformDir, "csharp_enums.h"), outputText.ToString());
11 changes: 11 additions & 0 deletions src/monogame/include/csharp_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

typedef char cschar;
typedef unsigned char csbyte;
typedef short csshort;
typedef unsigned short csushort;
typedef int csint;
typedef unsigned int csuint;
typedef long long cslong;
typedef unsigned long long csulong;
typedef bool csbool;
Loading

0 comments on commit 0cf7078

Please sign in to comment.