Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike/virtual methods #197

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Generator/Gir/GClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ public class GClass : GInterface
[XmlElement ("field")]
public List<GField> Fields { get; set; } = default!;

[XmlElement("virtual-method")]
public List<GVirtualMethod> VirtualMethods { get; set; } = default!;

[XmlAttribute("parent")]
public string? Parent { get; set; }

Expand Down
16 changes: 16 additions & 0 deletions Generator/Gir/GVirtualMethod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.Xml.Serialization;

namespace Gir
{
public class GVirtualMethod : GMethod
{
#region Properties

[XmlAttribute("invoker")]
public string? Invoker { get; set; }

public bool HasInvoker => Invoker is not null;

#endregion
}
}
18 changes: 14 additions & 4 deletions Generator/Resolver/TypeResolver.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Gir;

namespace Generator
Expand Down Expand Up @@ -29,8 +31,6 @@ public ResolvedType(string type, Direction dir = Direction.Value, string attribu

public override string ToString() => GetTypeString();

// public string GetTypeString() => Attribute + (IsRef ? "ref " : string.Empty) + Type;

public string GetTypeString() => Attribute + Direction switch
{
Direction.Value => Type,
Expand All @@ -42,7 +42,6 @@ public ResolvedType(string type, Direction dir = Direction.Value, string attribu
};

public string GetFieldString() => Direction == Direction.Value ? Type : "IntPtr";

#endregion

#region IEquatable<ResolvedType> Implementation
Expand Down Expand Up @@ -125,7 +124,7 @@ public TypeResolver(AliasResolver resolver)

public ResolvedType Resolve(IType typeInfo) => typeInfo switch
{
GField f when f.Callback is { } => new ResolvedType("IntPtr"),
GField f when f.Callback is { } c => ResolveCallback(c),
{ Array: { CType: { } n } } when n.EndsWith("**") => new ResolvedType("IntPtr", Direction.InOut),
{ Type: { } gtype } => GetTypeName(ConvertGType(gtype, typeInfo is GParameter, typeInfo)),
{ Array: { Length: { } length, Type: { CType: { } } gtype } } => GetTypeName(ResolveArrayType(gtype, typeInfo is GParameter, length)),
Expand All @@ -134,6 +133,17 @@ public TypeResolver(AliasResolver resolver)
{ Array: { } } => new ResolvedType("IntPtr"),
_ => throw new NotSupportedException("Type is missing supported Type information")
};

private ResolvedType ResolveCallback(GCallback callback)
{
ResolvedType returntype = Resolve(callback.ReturnValue ?? throw new Exception("Missing return for callback"));

List<ResolvedType> parameters = callback.Parameters?.AllParameters.Select(Resolve).ToList() ?? new ();
parameters.Add(returntype);

var parametersString = string.Join(", ", parameters.Select(x => x.GetFieldString()));
return new ResolvedType($"unsafe delegate* unmanaged<{parametersString}>");
}

private MyType StringArray(string length, bool isParameter) => new MyType("byte")
{
Expand Down
2 changes: 1 addition & 1 deletion Generator/Templates/Shared/struct.sbntxt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace {{ namespace }}

{{ include 'header.sbntxt' this ~}}
[StructLayout(LayoutKind.Sequential)]
public partial struct {{ name }}
public unsafe partial struct {{ name }}
{
#region Fields
{{~ for field in fields }}
Expand Down
1 change: 1 addition & 0 deletions Libs/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<RepositoryUrl>https://github.com/GirCore/gir.core</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<PropertyGroup Condition="$(GirComments) == 'True'">
Expand Down
8 changes: 8 additions & 0 deletions Libs/GObject/Classes/Global.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace GObject
{
public static partial class Global
{
public static Type GetParentType(Type t)
=> new Type(Native.type_parent(t.Value));
}
}
2 changes: 1 addition & 1 deletion Libs/GObject/Classes/Object.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public Object(params ConstructParameter[] properties)
}

/// <summary>
/// Initializes a wrapper for an existing object
/// Initializes a wrapper for an existing objectTypedes
/// </summary>
/// <param name="handle"></param>
protected Object(IntPtr handle)
Expand Down
3 changes: 3 additions & 0 deletions Libs/Gtk3/Classes/Button.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;
using GLib;
using GObject;

Expand Down Expand Up @@ -128,5 +129,7 @@ public bool UseActionAppearance
}

#endregion


}
}
51 changes: 49 additions & 2 deletions Samples/Gtk3/QuickStart/Program.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Gtk;
using System;
using System.Runtime.InteropServices;
using GObject;
using Gtk;
using Global = Gtk.Global;

namespace GtkDemo
Expand Down Expand Up @@ -46,7 +49,7 @@ public static void Main(string[] args)

// Add some widgets to the notebook
["Page1"] = new Label("Hello C#"),
["Page2"] = new Button("Open")
["Page2"] = new MyButton("Open")
{
// Register a callback for the button
[Button.ClickedSignal] = OnOpenButtonClick,
Expand Down Expand Up @@ -131,4 +134,48 @@ public static void OnCloseButtonClick(Button sender, System.EventArgs args)

#endregion
}

public class MyButton : Button
{
private unsafe static ButtonClass* buttonClass;

private static unsafe void ClassInit(GObject.Type gClass, System.Type type, IntPtr classData)
{
var myButtonClass = (ButtonClass*) TypeHelper.GetClassPointer(gClass);
myButtonClass->pressed = &StaticPressed;

var buttonType = GObject.Global.GetParentType(gClass);
buttonClass = (ButtonClass*) TypeHelper.GetClassPointer(buttonType);
}

public MyButton(string label) : base(label)
{

}

[UnmanagedCallersOnly]
private static void StaticPressed(nint instance)
{
if (TryWrapHandle<MyButton>(instance, out var obj))
{
obj.Pressed();
}
}

private void BasePressed()
{
unsafe
{
buttonClass->pressed(Handle);
}
}

//This could be a potential attribute to trigger code generation for virtual methods
//[Overrides(VirtualMethod.Pressed)]
public void Pressed()
{
BasePressed();
Console.WriteLine("TestTest");
}
}
}
1 change: 1 addition & 0 deletions Samples/Gtk3/QuickStart/QuickStart.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
</ItemGroup>

<PropertyGroup>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
<Nullable>enable</Nullable>
Expand Down