Tencent / puerts

PUER(普洱) Typescript. Let's write your game in UE or Unity with TypeScript.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Unity] Bug: JS派生C#类后,super 访问异常

Geequlim opened this issue · comments

前置阅读 | Pre-reading

Puer的版本 | Puer Version

2.0.5

Unity的版本 | Unity Version

2022.3.17

发生在哪个平台 | Platform

Editor(win)

错误信息 | Error Message

使用案例:通过TS 重写FariyGUI的GLoader实现加载并展示远程图像

通过为C# GLoader 的 url 属性赋值时调用 LoadExternal 方法,里面调用了JS的实现。JS的实现中访问
super.url 在编辑器中报错url的setter调用没有目标对象,发布程序后能够正常工作。

报错信息

Error: c# exception:Non-static method requires a target.,stack:  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00019] in <e3b07672ffbd43c1838e1ebbe94cbdf5>:0 
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <e3b07672ffbd43c1838e1ebbe94cbdf5>:0 
  at Puerts.OverloadReflectionWrap.Invoke (Puerts.JSCallInfo jsCallInfo) [0x00083] in ./tiny_modules/puerts@2.0.5/Runtime/Src/Default/Wrapper/ReflectionWrap.cs:319 
  at Puerts.MethodReflectionWrap.Invoke (System.IntPtr isolate, System.IntPtr info, System.IntPtr self, System.Int32 argumentsLen) [0x00070] in ./tiny_modules/puerts@2.0.5/Runtime/Src/Default/Wrapper/ReflectionWrap.cs:404 
    at TinyFairyGUIGLoader.loadExternal (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/framework/unity/tiny/game/modules/fairygui/index.ts:310:42)
    at TinyFairyGUIGLoader.__loadExternal (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/framework/unity/tiny/game/modules/fairygui/index.ts:296:36)
    at LotteryDetailWindow.view.m_list.itemRenderer (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/game/main-game/lottery/LotteryDetail.window.ts:51:18)
    at LotteryDetailWindow.<anonymous> (/home/geequlim/Documents/work/super-playground/project/Build/scripts/webpack:///src/game/main-game/lottery/LotteryDetail.window.ts:92:20)
    at Generator.next (<anonymous>)
    at fulfilled (/home/geequlim/Documents/work/super-playground/project/Build/scripts/bundle.js:22100:24),stack:  at Puerts.GenericDelegate.Action () [0x00032] in ./tiny_modules/puerts@2.0.5/Runtime/Src/Default/JSType/GenericDelegate.cs:432 
  at FairyGUI.GLoader.LoadExternal () [0x0000f] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:490 
  at FairyGUI.GLoader.LoadContent () [0x0003c] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:405 
  at FairyGUI.GLoader.set_url (System.String value) [0x00021] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:97 
  at FairyGUI.GLoader.set_icon (System.String value) [0x00001] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLoader.cs:105 
  at FairyGUI.GLabel.set_icon (System.String value) [0x0000e] in /home/geequlim/Documents/work/super-playground/project/Assets/Plugins/FairyGUI/Scripts/UI/GLabel.cs:34 
  at (wrapper managed-to-native) System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo,object,object[],System.Exception&)
  at System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x0006a] in <e3b07672ffbd43c1838e1ebbe94cbdf5>:0 

问题重现 | Bug reproduce

FairyGUI.GLoade C#关键代码
namespace FairyGUI {
    public class GLoader : GObject, IAnimationGear, IColorGear {

#if FAIRYGUI_PUERTS
        public Action __loadExternal;
        public Action<NTexture> __freeExternal;
#endif

        public string url {
            get { return _url; }
            set {
                if (_url == value) return;

                ClearContent();
                _url = value;
                LoadContent();
                UpdateGear(7);
            }
        }

        protected void LoadContent() {
            ClearContent();

            if (string.IsNullOrEmpty(_url))
                return;

            if (_url.StartsWith(UIPackage.URL_PREFIX))
                LoadFromPackage(_url);
            else
                LoadExternal();
        }

        virtual protected void LoadExternal()
        {
#if FAIRYGUI_PUERTS
            if (__loadExternal != null)
            {
                __loadExternal();
                return;
            }
#endif
            Texture2D tex = (Texture2D)Resources.Load(_url, typeof(Texture2D));
            if (tex != null)
                onExternalLoadSuccess(new NTexture(tex));
            else
                onExternalLoadFailed();
        }

    }
}
TypeScript关键代码
export class TinyFairyGUIGLoader extends FairyGUI.GLoader {

	static getOverrideURL(url: string): string { return url; }

	constructor() {
		super();
		this.__freeExternal = this.freeExternal.bind(this);
		this.__loadExternal = this.loadExternal.bind(super);
	}

	public get url(): string { return this.$url || this.$internalURL; }
	public set url(value: string) {
		this.$url = value;
		super.url = this.$internalURL = TinyFairyGUIGLoader.getOverrideURL(this.url);
	}
	private $internalURL: string;
	private $url: string;

	protected loadExternal() {
		const url = super.url; // <<< 编辑器中这里报错
		// TODO: 这里忽略具体加载逻辑
	}
}

首先我一向不建议ts继承c#。
其次即使我按你说的“JS派生C#类后”,super 访问并无异常。
应该你工程还有别的什么导致了问题。我从你的描述没法重现,或者你可以提供个干净的demo。