Skip to content

Commit ce625b7

Browse files
authored
Merge pull request #3 from dcronqvist/dev
Update to automatic generation of native binding
2 parents e0a9e6d + 54c9e2f commit ce625b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+4294
-4380
lines changed

.editorconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Top-most EditorConfig file
2+
root = true
3+
4+
# C# files
5+
[*.cs]
6+
indent_style = space
7+
indent_size = 2

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@
33
##
44
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
55

6+
.glfw/
67
.vscode/
78
nupkg/
89
runtimes/
910

11+
# Generated files
12+
DotGLFW/Generated/
13+
1014
# User-specific files
1115
*.rsuser
1216
*.suo

.scripts/gen_debug_args.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Will create a json representation of the debug launch arguments for a specified dll file
2+
# Usage: ./gen_debug_args.sh <path_to_dll> <cwd> <args>
3+
4+
# Check if the correct number of arguments were passed
5+
if [ "$#" -ne 3 ]; then
6+
echo "Usage: ./gen_debug_args.sh <path_to_dll> <cwd> <args>"
7+
exit 1
8+
fi
9+
10+
# Get absolute path to the dll
11+
dll_path=$(realpath $1)
12+
13+
# Get absolute path to the cwd
14+
cwd=$(realpath $2)
15+
16+
# Create the json representation of the debug launch arguments
17+
launch_args="{\"type\":\"coreclr\",\"request\":\"launch\",\"program\":\"$dll_path\",\"cwd\":\"$cwd\",\"just_my_code\":false,\"args\":\"$3\"}"
18+
19+
# Url encode the json representation
20+
launch_args=$(echo $launch_args | jq -r @uri)
21+
22+
# Print the url encoded json representation
23+
echo $launch_args

DotGLFW.Example/Program.cs

Lines changed: 79 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -5,96 +5,101 @@ namespace DotGLFW.Example;
55

66
public class Program
77
{
8-
private const int GL_COLOR_BUFFER_BIT = 0x00004000;
9-
private delegate void glClearColorHandler(float r, float g, float b, float a);
10-
private delegate void glClearHandler(int mask);
11-
private static glClearColorHandler glClearColor;
12-
private static glClearHandler glClear;
8+
private const int GL_COLOR_BUFFER_BIT = 0x00004000;
139

14-
static void Main(string[] args)
15-
{
16-
Glfw.Init();
17-
18-
// Set some common hints for the OpenGL profile creation
19-
Glfw.WindowHint(Hint.ClientAPI, ClientAPI.OpenGLAPI);
20-
Glfw.WindowHint(Hint.ContextVersionMajor, 3);
21-
Glfw.WindowHint(Hint.ContextVersionMinor, 3);
22-
Glfw.WindowHint(Hint.OpenGLProfile, OpenGLProfile.CoreProfile);
23-
Glfw.WindowHint(Hint.DoubleBuffer, true);
24-
Glfw.WindowHint(Hint.Decorated, true);
25-
Glfw.WindowHint(Hint.OpenGLForwardCompat, true);
26-
Glfw.WindowHint(Hint.Resizable, false);
10+
private delegate void glClearColorHandler(float r, float g, float b, float a);
11+
private delegate void glClearHandler(int mask);
12+
private static glClearColorHandler glClearColor;
13+
private static glClearHandler glClear;
2714

28-
var WIDTH = 800;
29-
var HEIGHT = 600;
30-
var TITLE = "DotGLFW Example";
15+
static void Main(string[] args)
16+
{
17+
Glfw.Init();
3118

32-
// Create window
33-
var window = Glfw.CreateWindow(WIDTH, HEIGHT, TITLE, Monitor.NULL, Window.NULL);
34-
Glfw.MakeContextCurrent(window);
19+
var versionString = Glfw.GetVersionString();
20+
Console.WriteLine($"GLFW Version: {versionString}");
3521

36-
// Enable VSYNC
37-
Glfw.SwapInterval(1);
22+
Glfw.WindowHint(WindowHint.ClientAPI, ClientAPI.OpenGLAPI);
23+
Glfw.WindowHint(WindowHint.ContextVersionMajor, 3);
24+
Glfw.WindowHint(WindowHint.ContextVersionMinor, 3);
25+
Glfw.WindowHint(WindowHint.OpenGLProfile, OpenGLProfile.CoreProfile);
26+
Glfw.WindowHint(WindowHint.DoubleBuffer, true);
27+
Glfw.WindowHint(WindowHint.Decorated, true);
28+
Glfw.WindowHint(WindowHint.OpenGLForwardCompat, true);
29+
Glfw.WindowHint(WindowHint.Resizable, true);
30+
Glfw.WindowHint(WindowHint.Visible, false);
3831

39-
var primaryMonitor = Glfw.GetPrimaryMonitor();
40-
Glfw.GetMonitorWorkarea(primaryMonitor, out var x, out var y, out var width, out var height);
41-
VideoMode primaryVideoMode = Glfw.GetVideoMode(primaryMonitor);
32+
var WIDTH = 800;
33+
var HEIGHT = 600;
34+
var TITLE = "DotGLFW Example";
4235

43-
int refreshRate = primaryVideoMode.RefreshRate;
44-
double delta = 1.0 / refreshRate;
45-
Console.WriteLine($"Refresh rate: {refreshRate} Hz");
36+
// Create window
37+
var window = Glfw.CreateWindow(WIDTH, HEIGHT, TITLE, null, null);
38+
var primary = Glfw.GetPrimaryMonitor();
4639

47-
// Find center position based on window and monitor sizes
48-
Glfw.SetWindowPos(window, width / 2 - WIDTH / 2, height / 2 - HEIGHT / 2);
40+
Glfw.GetMonitorWorkarea(primary, out var wx, out var wy, out var ww, out var wh);
41+
Glfw.SetWindowPos(window, wx + ww / 2 - WIDTH / 2, wy + wh / 2 - HEIGHT / 2);
42+
Glfw.ShowWindow(window);
4943

50-
glClearColor = Marshal.GetDelegateForFunctionPointer<glClearColorHandler>(Glfw.GetProcAddress("glClearColor"));
51-
glClear = Marshal.GetDelegateForFunctionPointer<glClearHandler>(Glfw.GetProcAddress("glClear"));
44+
Glfw.MakeContextCurrent(window);
5245

53-
Glfw.SetKeyCallback(window, (window, key, scancode, action, mods) =>
54-
{
55-
Console.WriteLine($"Key: {key}, Scancode: {scancode}, Action: {action}, Mods: {mods}");
56-
});
46+
// Enable VSYNC
47+
Glfw.SwapInterval(1);
5748

58-
Glfw.SetWindowIcon(window, [CreateIcon()]);
49+
var videoMode = Glfw.GetVideoMode(primary);
50+
int refreshRate = videoMode.RefreshRate;
51+
double delta = 1.0 / refreshRate;
5952

60-
GC.Collect();
53+
glClearColor = Marshal.GetDelegateForFunctionPointer<glClearColorHandler>(
54+
Glfw.GetProcAddress("glClearColor"));
55+
glClear = Marshal.GetDelegateForFunctionPointer<glClearHandler>(
56+
Glfw.GetProcAddress("glClear"));
6157

62-
while (!Glfw.WindowShouldClose(window))
63-
{
64-
Glfw.PollEvents();
65-
Glfw.SwapBuffers(window);
58+
Glfw.SetWindowIcon(window, [CreateIcon()]);
6659

67-
double currentTime = Glfw.GetTime();
68-
SetHueShiftedColor(currentTime * delta * 200);
60+
Glfw.SetKeyCallback(window, (window, key, scancode, action, mods) =>
61+
{
62+
Console.WriteLine($"Key: {key}, Scancode: {scancode}, Action: {action}, Mods: {mods}");
63+
});
6964

70-
// Clear the buffer to the set color
71-
glClear(GL_COLOR_BUFFER_BIT);
72-
}
73-
}
65+
GC.Collect();
7466

75-
private static void SetHueShiftedColor(double time)
67+
while (!Glfw.WindowShouldClose(window))
7668
{
77-
// Set the clear color to a shifted hue
78-
float r = (float)(Math.Sin(time) / 2 + 0.5);
79-
float g = (float)(Math.Sin(time + 2) / 2 + 0.5);
80-
float b = (float)(Math.Sin(time + 4) / 2 + 0.5);
81-
float a = 1.0f;
82-
glClearColor(r, g, b, a);
83-
}
69+
Glfw.PollEvents();
70+
Glfw.SwapBuffers(window);
8471

85-
private static Image CreateIcon()
86-
{
87-
var image = new Image
88-
{
89-
Width = 2,
90-
Height = 2,
91-
Pixels = [
92-
0, 0, 0, 255,
93-
255, 0, 0, 255,
94-
0, 255, 0, 255,
95-
0, 0, 255, 255
96-
]
97-
};
98-
return image;
72+
double currentTime = Glfw.GetTime();
73+
SetHueShiftedColor(currentTime * delta * 200);
74+
75+
// Clear the buffer to the set color
76+
glClear(GL_COLOR_BUFFER_BIT);
9977
}
78+
}
79+
80+
private static void SetHueShiftedColor(double time)
81+
{
82+
// Set the clear color to a shifted hue
83+
float r = (float)(Math.Sin(time) / 2 + 0.5);
84+
float g = (float)(Math.Sin(time + 2) / 2 + 0.5);
85+
float b = (float)(Math.Sin(time + 4) / 2 + 0.5);
86+
float a = 1.0f;
87+
glClearColor(r, g, b, a);
88+
}
89+
90+
private static Image CreateIcon()
91+
{
92+
var image = new Image
93+
{
94+
Width = 2,
95+
Height = 2,
96+
Pixels = [
97+
0, 0, 0, 255,
98+
255, 0, 0, 255,
99+
0, 255, 0, 255,
100+
0, 0, 255, 255
101+
]
102+
};
103+
return image;
104+
}
100105
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>disable</ImplicitUsings>
7+
<Nullable>disable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="HtmlAgilityPack" Version="1.11.61" />
12+
</ItemGroup>
13+
14+
</Project>

DotGLFW.Generator/Extensions.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Linq;
3+
4+
namespace DotGLFW.Generator;
5+
6+
public static partial class Extensions
7+
{
8+
public static string Remove(this string str, string toRemove)
9+
{
10+
return str.Replace(toRemove, "");
11+
}
12+
13+
public static string FixSpaces(this string str)
14+
{
15+
if (!str.Contains(" "))
16+
{
17+
return str;
18+
}
19+
20+
if (!str.Split(" ").Where(x => x != "").Any())
21+
{
22+
return str;
23+
}
24+
25+
return str.Split(" ").Where(x => x != "").Aggregate((x, y) => $"{x} {y}");
26+
}
27+
28+
public static string FixNewlines(this string str)
29+
{
30+
if (!str.Contains("\n"))
31+
{
32+
return str;
33+
}
34+
35+
if (!str.Split("\n").Where(x => x != "").Any())
36+
{
37+
return str;
38+
}
39+
40+
return str.Split("\n").Where(x => x != "").Aggregate((x, y) => $"{x} {y}");
41+
}
42+
43+
public static int Count(this string str, char c)
44+
{
45+
return str.Count(x => x == c);
46+
}
47+
48+
public static string Repeat(this string str, int count)
49+
{
50+
return string.Concat(Enumerable.Repeat(str, count));
51+
}
52+
53+
public static string Capitalize(this string str)
54+
{
55+
if (str.Length <= 1)
56+
return str.ToUpper();
57+
58+
return char.ToUpper(str[0]) + str.Substring(1);
59+
}
60+
}

DotGLFW.Generator/GLFWProvider.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.IO;
2+
3+
namespace DotGLFW.Generator;
4+
5+
public class GLFWProvider : IGLFWProvider
6+
{
7+
private readonly string _glfwRepoPath;
8+
9+
public GLFWProvider(string glfwRepoPath)
10+
{
11+
_glfwRepoPath = glfwRepoPath;
12+
}
13+
14+
public string ReadGLFWRepoFile(string filePath)
15+
{
16+
using var reader = new StreamReader(Path.Combine(_glfwRepoPath, filePath));
17+
return reader.ReadToEnd();
18+
}
19+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using System.Collections;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace DotGLFW.Generator;
7+
8+
public partial class Generator
9+
{
10+
public void GenerateEnums(ParsedAPI api)
11+
{
12+
var enums = api.MacroCollections;
13+
enums.ToList().ForEach(GenerateEnum);
14+
}
15+
16+
private void GenerateEnum(MacroCollection macroCollection)
17+
{
18+
var content = new StringBuilder();
19+
WriteFileHeader(content);
20+
21+
content.AppendLine("using static DotGLFW.NativeGlfw;");
22+
content.AppendLine("namespace DotGLFW;");
23+
content.AppendLine();
24+
content.AppendLine("/// <summary>");
25+
content.AppendLine($"/// Wrapping enum for {macroCollection.Name}.");
26+
content.AppendLine("/// </summary>");
27+
content.AppendLine($"public enum {macroCollection.Name}");
28+
content.AppendLine("{");
29+
30+
foreach (var macro in macroCollection.Macros)
31+
{
32+
var csharpName = ConvertEnumName(macro.Name, macroCollection.PrefixToRemove, macroCollection.SuffixToRemove);
33+
if (macro.TryGetValue(out var value))
34+
{
35+
content.AppendLine($" /// <inheritdoc cref=\"NativeGlfw.{macro.Name}\" />");
36+
content.AppendLine($" {csharpName} = NativeGlfw.{macro.Name},");
37+
}
38+
}
39+
40+
content.AppendLine("}");
41+
42+
_sourceWriter.WriteToFile($"Enum.{macroCollection.Name}.gen.cs", content.ToString());
43+
}
44+
45+
private string ConvertEnumName(string name, string prefixToRemove, string suffixToRemove)
46+
{
47+
string withoutPrefixSuffix = name;
48+
if (!string.IsNullOrEmpty(prefixToRemove))
49+
{
50+
withoutPrefixSuffix = withoutPrefixSuffix.Replace(prefixToRemove, "");
51+
}
52+
if (!string.IsNullOrEmpty(suffixToRemove))
53+
{
54+
withoutPrefixSuffix = withoutPrefixSuffix.Replace(suffixToRemove, "");
55+
}
56+
57+
var split = withoutPrefixSuffix.Split('_');
58+
var result = new StringBuilder();
59+
foreach (var part in split)
60+
{
61+
result.Append(part.ToLower().Capitalize());
62+
}
63+
var final = result.ToString();
64+
if (char.IsDigit(final[0]))
65+
{
66+
final = "D" + final;
67+
}
68+
return final;
69+
}
70+
}

0 commit comments

Comments
 (0)