Closed FreakTheMighty closed 2 years ago
I added a method to manually add an extension method. Is this what you want?
public static class ExtensionTest
{
public static void ResetAll(this Transform transform)
{
transform.localPosition = Vector3.zero;
transform.localRotation = Quaternion.identity;
transform.localScale = Vector3.one;
}
}
bindingManager.AddExtensionMethod<Transform>(ExtensionTest.ResetAll); // expose single extension method
I haven't checked whether it works in static-bind mode, I'll fix further problems later.
That looks about right. I’ve only used static bindings, so I should be able to test that soon.
🤔 I'm struggling to get this to work just right. Given this extension
public static class RxBindExtensions
{
public static IDisposable Subscribe(this IObservable<Unit> source, ScriptFunction onNext)
{
return source.Subscribe((val) => onNext?.Invoke(val));
}
}
This binding
bindingManager.AddExtensionMethod<IObservable<Unit>, ScriptFunction, IDisposable>(RxBindExtensions.Subscribe);
I get this output
[MonoPInvokeCallbackAttribute(typeof(JSCFunction))]
public static JSValue Bind_Subscribe(JSContext ctx, JSValue this_obj, int argc, JSValue[] argv)
{
try
{
if (argc == 1)
{
UniRx.Subject<UniRx.Unit> self;
if (!js_get_classvalue(ctx, this_obj, out self))
{
throw new ThisBoundException();
}
System.IObserver<UniRx.Unit> arg0;
if (!js_get_classvalue(ctx, argv[0], out arg0))
{
throw new ParameterException(typeof(UniRx.Subject<UniRx.Unit>), "Subscribe", typeof(System.IObserver<UniRx.Unit>), 0);
}
var ret = self.Subscribe(arg0);
return js_push_classvalue(ctx, ret);
}
throw new NoSuitableMethodException("Subscribe", argc);
}
catch (Exception exception)
{
return JSApi.ThrowException(ctx, exception);
}
}
I think the templated methods might be complicating this. I believe that arg0
should be of type ScriptFunction
.
I tried with a similar situation, but can't reproduce this issue. Here is the code I use:
// a generic interface type
public interface GenericExample<T>
{
}
// the extension method for the concrete type of this generic interface, with a ScriptFunction as parameter
public static IDisposable TestWithConcreteGeneric(this GenericExample<GameObject> self, ScriptFunction function)
{
function?.Invoke();
return null;
}
It generates the glue code:
[MonoPInvokeCallbackAttribute(typeof(JSCFunction))]
public static JSValue Bind_TestWithConcreteGeneric(JSContext ctx, JSValue this_obj, int argc, JSValue[] argv)
{
try
{
if (argc == 1)
{
Example.GenericExample<UnityEngine.GameObject> self;
if (!js_get_classvalue(ctx, this_obj, out self))
{
throw new ThisBoundException();
}
QuickJS.ScriptFunction arg0;
if (!js_get_classvalue(ctx, argv[0], out arg0))
{
throw new ParameterException(typeof(Example.ExtensionTest), "TestWithConcreteGeneric", typeof(QuickJS.ScriptFunction), 0);
}
var ret = Example.ExtensionTest.TestWithConcreteGeneric(self, arg0);
return js_push_classvalue(ctx, ret);
}
throw new NoSuitableMethodException("TestWithConcreteGeneric", argc);
}
catch (Exception exception)
{
return JSApi.ThrowException(ctx, exception);
}
}
Is there any other condition being missing?
I'm curious if there is anyway to specify that a particular extension method should be used when generating bindings for a particular type? I'm doing this:
Which eposes a
Subscribe
method. The method, however, has a number of extension methods. I'd like to specify which method is selected. This would be especially useful, as it would allow me to write some more clean JS <-> C# interactions. For example, in this case I would like to create an extension method that handles JS functions, like so.My current solution was to edit the generated code, but obviously that won't scale very well.
Thoughts?