puerts icon indicating copy to clipboard operation
puerts copied to clipboard

[Unity] suggestion:JsEnv.Eval<> 支持 ref 参数作为 Action 参数

Open sesky4 opened this issue 2 years ago • 4 comments

背景: 根据 这里的文档faq

参数含ref,out的修饰,目前尚未支持,解决办法:填写issues来提需求

JsEnv.Eval<> 提供了将 js 函数转换为 c# Action 的能力,但是没有办法绑定 ref / in /out 变量,这对于希望在函数内修改一个值类型对象时很不方便,例如

struct MyValueType {
    public int Value;
}

var jsFuncWithoutRef = jsEnv.Eval<Action<MyValueType>>("(obj) => { obj.Value = 42;}");

var obj = new MyValueType{ Value = 41 };
jsFuncWithoutRef( obj );

Debug.Log( obj.Value ); // 输出41,但是我希望能够修改 Value 为 42

请问是否可以支持绑定 ref/in/out 参数的功能? ❤️

期望使用方式

1. Action
jsEnv.Eval<Action<Ref<MyValueType>>>("(obj) => { obj.Value = 42;}");

2. Delegate
public delegate void MyFunc(ref MyValueType obj);
jsEnv.Eval<MyFunc>( "(obj) => { obj.Value = 42;}");

sesky4 avatar Jun 28 '23 06:06 sesky4

ref/out 参数不是这个意思吧。

你写的这个情况,JS侧直接return一个Vector出来就行了,和用ref/out是一样的效果,都会产生一次拷贝。

ref/out对应的能力是多返回值。JS函数虽然不支持多返回值,但你可以返回一个JSObject出来,然后再get不同key的内容。当然效率起见设计函数尽量设计成单返回值最好。

zombieyang avatar Jun 28 '23 07:06 zombieyang

@zombieyang 在函数内修改值只是个举例,实际上因为 Unity DOTS 技术栈基本是在和 struct 打交道,要用的 ref 的地方是很多的

sesky4 avatar Jul 31 '23 03:07 sesky4

你好 @zombieyang ,当前我的使用场景是这样:

在 c# 侧定义了一些事件处理delegate

PlayerStatus 和 DamageInfo 都是 struct

public delegate void OnPlayerTakeDamage( ref PlayerStatus status, ref DamageInfo damageInfo);

然后希望在 JS 侧注册这些处理函数

player.onPlayerTakeDamage = (status, damageInfo) => {
    ...
}

但是当前会报 exception,无法将 js 侧的 lambda 转换为 c# delegate,这里 当前有办法支持 / 未来有计划支持 吗?

谢谢。

sesky4 avatar Jul 31 '23 06:07 sesky4

你好 @zombieyang ,当前我的使用场景是这样:

在 c# 侧定义了一些事件处理delegate

PlayerStatus 和 DamageInfo 都是 struct

public delegate void OnPlayerTakeDamage( ref PlayerStatus status, ref DamageInfo damageInfo);

然后希望在 JS 侧注册这些处理函数

player.onPlayerTakeDamage = (status, damageInfo) => {
    ...
}

但是当前会报 exception,无法将 js 侧的 lambda 转换为 c# delegate,这里 当前有办法支持 / 未来有计划支持 吗?

谢谢。

你QQ私聊下我,我最近正好搞了个类似的东西,可能会和你需要的很像

zombieyang avatar Jul 31 '23 06:07 zombieyang