Closed GeorgeS2019 closed 2 months ago
Please provide an MRP to help us reproduce this issue.
using System.Reflection;
using Godot;
public static class GDExtensionHelper
{
private static readonly System.Collections.Generic.Dictionary<string, GodotObject> _instances = [];
/// <summary>
/// Calls a static method within the given type.
/// </summary>
/// <param name="className">The type name.</param>
/// <param name="method">The method name.</param>
/// <param name="arguments">The arguments.</param>
/// <returns>The return value of the method.</returns>
public static Variant Call(string className, string method, params Variant[] arguments)
{
if (!_instances.TryGetValue(className, out var instance))
{
instance = ClassDB.Instantiate(className).AsGodotObject();
_instances[className] = instance;
}
return instance.Call(method, arguments);
}
/// <summary>
/// Try to cast the script on the supplied <paramref name="godotObject"/> to the <typeparamref name="T"/> wrapper type,
/// if no script has attached to the type, or the script attached to the type does not inherit the <typeparamref name="T"/> wrapper type,
/// a new instance of the <typeparamref name="T"/> wrapper script will get attaches to the <paramref name="godotObject"/>.
/// </summary>
/// <remarks>The developer should only supply the <paramref name="godotObject"/> that represents the correct underlying GDExtension type.</remarks>
/// <param name="godotObject">The <paramref name="godotObject"/> that represents the correct underlying GDExtension type.</param>
/// <returns>The existing or a new instance of the <typeparamref name="T"/> wrapper script attached to the supplied <paramref name="godotObject"/>.</returns>
public static T Bind<T>(GodotObject godotObject) where T : GodotObject
{
if (godotObject is T wrapperScript) return wrapperScript;
var instanceId = godotObject.GetInstanceId();
godotObject.SetScript(ResourceLoader.Load(typeof(T).GetCustomAttribute<ScriptPathAttribute>()!.Path));
return (T)GodotObject.InstanceFromId(instanceId);
}
/// <summary>
/// Creates an instance of the GDExtension <typeparam name="T"/> type, and attaches the wrapper script to it.
/// </summary>
/// <returns>The wrapper instance linked to the underlying GDExtension type.</returns>
public static T Instantiate<T>(StringName className) where T : GodotObject
{
return Bind<T>(ClassDB.Instantiate(className).As<GodotObject>());
}
}
Perhaps it is time to setup Unit tests to check if it is possible just to Instantiate()
each created class.
MediaPipeFaceLandmarker.Instantiate()
https://github.com/Delsin-Yu/CSharp-Wrapper-Generator-for-GDExtension/issues/10
That's a good point, but let's first fix this issue at lest.
@Delsin-Yu Overall, I am surprised how great the generated wrappers. I could get through, most time.
I'm having trouble reproducing the issue you experienced on my end, please provide a sample project if possible.
var task: MediaPipeFaceLandmarker
task = MediaPipeFaceLandmarker.new() #<=== this step fail
task.initialize(base_options, running_mode, 1, 0.5, 0.5, 0.5, true)
task.result_callback.connect(self._result_callback)
MediaPipeFaceLandmarker task = MediaPipeFaceLandmarker.Instantiate();
Using the gdunit4mono test adapter, it is possible to load a specific scene ( attach to either GDScript or csharp ) . a quick way to check through porting of GDScript to Csharp
I woundn't say porting is a quick way, but that's a good point. Anyway, I see the issue, working on it.
Multiple custom attributes of the same type 'Godot.ScriptPathAttribute' found.
The instantiate() of this class is probably called multiple times, more than once.
Perhaps there is a way to check that the class is not instantiated more than once.
No, it's simply the issue of this line.
typeof(T).GetCustomAttribute<ScriptPathAttribute>()
No, it's simply the issue of this line.
Can you elaborate?
MediaPipeFaceLandmarker
is inheriting MediaPipeTask
, both of them have ScriptPathAttribute
s, and GetCustomAttribute
is having trouble on handling that.
Inheritance is an issue!
Need feedback how to debug this error.