llint

Results 7 issues of llint

When discussing Rust Futures, pretty much all the information I found online talks about Futures that are coded by a human user, e.g.: TimerFuture, SocketReadFuture, etc.. These Futures are what...

The TextInput seems to be missing one important feature: the ability for user to register a callback when the `Enter` key is pressed - the user is left the opportunities...

msgpack.js: line 73, it should be `if (msg == null)`, instead of `if (!msg)` - if `msg` as unpacked correctly as `0`, would silent the 'msg' emission. Please fix. ps:...

In the `Stream` wrapper of msgpack.js, it seems that the `send` function doesn't handle the underlying stream's `writable.'drain'` event, even though in most cases, `stream.write` would succeed, but for high...

Currently `MsgPack.Deserialize` eventually invokes `Stream.Read` which is blocking. It would be great if there is an asynchronous version `BeginDeserialize/EndDeserialize` that takes advantage of `Stream.BeginRead` / `Stream.EndRead`, so to make the...

enhancement
wontfix

## detail | 详细描述 [TypeScript/EntryPoint.ts](https://gist.github.com/llint/fe0295af14c471e48620b3bf8d08bb22) [TypeScript/ScriptBindings/Game/Blueprints/B_PlayerController_C.ts](https://gist.github.com/llint/e2afc9776ae71997c9ab1a3638ffd17b) 在UE5中,如果想让PuerTS呈现出和UnLua类似的一个蓝图一个脚本绑定方式,并且可以在PuerTS下实现自动注册,可以在TypeScript根目录下创建上面EntryPoint.ts文件,然后将所有需要自动绑定mixin的脚本按蓝图的目录组织形式放到ScriptBindings目录下面。然后将TsGameInstance.cpp里面的JsEnv->Start的第一个参数改成`“EntryPoint”`,那么启动之后,该脚本会自动的将ScriptBindings目录下面的所有脚本文件基于路径和文件名规范(比如:`B_PlayerController_C.ts`)的方式,自动将蓝图类和这个ts类做mixin - 脚本的路径会被用来决定蓝图的asset path,因此这个路径需要和蓝图资产的路径对应。 EntryPoint.ts除了做mixin自动绑定,当然还可以做其他的初始化操作,但是注意 - 最终EntryPoint.ts仍然会从JsEnv.Start函数返回,UE引擎会重新获得控制权 - 所以从这种意义上来讲,任何在JsEnv->Start启动的脚本的主要用途其实就是进行脚本系统层级的注册和初始化操作。从UE引擎来讲,在运行时,真正脚本逻辑的触发其实是从C++到蓝图层再到ts层(或者UnLua的话就是Lua层)- 引擎始终是核心的驱动。

这两天深度试验了一下UE5下Mixin功能以及继承引擎类功能,分享一下我的体验 ##### [继承引擎类功能](https://puerts.github.io/docs/puerts/unreal/manual/) 继承引擎类功能的本质是Puerts自动 基于继承引擎类的ts脚本 生成对应的蓝图资源(代码:`PEBlueprintAsset.hpp`/`CodeAnalyze.tjs`),这样在UE编辑器中就可以对这个蓝图资源进行正常引用。比如一个`TS_Player.ts`内定义一个继承于`UE.Character`的`TS_Player`类,并将其默认导出,则Puerts会自动识别这个类,然后自动生成对应的`TS_Player.uasset`蓝图资源,该资源的父类和Native类均为引擎`Character`类。 生成对应蓝图资源的路径根目录由`JsEnv.Build.cs`内`TS_BLUEPRINT_PATH`定义,默认为`[/Game]/Blueprints/TypeScript`目录。生成的蓝图资源内的方法(或事件)与对应的ts脚本之间应该是做了类似蓝图Mixin功能的重定向(Mixin的实现逻辑我反而还没来得及看),这样蓝图内的方法或者事件被调用或者触发的时候,实际逻辑会被导向到对应脚本函数的逻辑。生成的蓝图资源本身就是普通的蓝图资源,并且生成的蓝图资源可以像普通蓝图一样进行修改(*)。 继承引擎类的成员变量,除了`ActorComponent`类型(或子类),默认在生成的蓝图里是不可见的 - 比如文档中的`FpsCamera`成员因为是一个`ActorComponent`子类,因此在蓝图中的Variables.Components下默认可见(但不可删除),而文档中的`tickCount`成员在生成蓝图中默认是不可见的。要让非ActorComponent类型的成员可见,需要对这些成员进行uproperty[标注](https://puerts.github.io/docs/puerts/unreal/uclass_extends#uproperty-ufunction):`@uproperty.uproperty(uproperty.BlueprintReadOnly)` 在生成对应蓝图资源的时候,系统会尝试加载对应路径下同名资源。如果资源不存在,那么就基于ts脚本生成一个新的蓝图资源;如果蓝图资源存在,目前Puerts的逻辑是以ts脚本为 _原型_,对存在的蓝图资源内同名的成员和方法做类型及参数调整(如有变化),最后删除蓝图中在原型ts脚本中不存在的成员和方法。 上述行为导致的结果是:虽然生成的蓝图是可以编辑的,可以在蓝图中增加新的成员变量及方法,但是一旦对应的原型ts脚本触发重新编译,那么上述行为会导致蓝图中新添加的成员和方法自动被删除。因此从使用流程的角度来讲,其实生成的蓝图是不应该被修改的,否则任何对于蓝图的修改都将在下一次原型ts触发重新编译的时候丢失!而且因为蓝图本身的不方便diff的特性(当然可以通过编辑器和P4/Git的集成进行diff),在团队合作过程中可能会导致比较大的问题。我不知道蓝图是否有一个标志可以将蓝图置为不可修改的状态来避免这个问题。或者另外两个思路: 1. 不删除新添加的成员和方法;但是对于 _合并_ 修改过的成员(类型改变)和方法(参数和返回改变)就比较麻烦 - or 2. 直接在蓝图里面标明该蓝图由对应的ts脚本生成,不可更改;然后Puerts的蓝图生成逻辑就可以更加简化:如果对应蓝图存在则直接删除这个蓝图,从零开始基于ts脚本重新生成该蓝图,这样原来的追踪和删除新添加和改变的成员和方法的逻辑就可以简化 所以实际体验下来,继承引擎类功能最大的优点可能只是可以通过只写一个ts脚本,实现自动生成对应蓝图的效果,而该蓝图其实并不包含任何实际的逻辑(逻辑都在原型ts脚本内),还不能修改,所以这个生成蓝图的功效并不大。 [Unreal Engine Angelscript](https://angelscript.hazelight.se/)实现了蓝图虚拟机的自动注入(需要引擎改动),不需要生成中间蓝图的方式,我觉得可能是最佳案例,但是可惜的是这个方案需要引擎的改动。 我甚至还考虑过通过原型ts脚本生成对应C++代码的方案,优势是代码diff更加直观,生成的C++类在蓝图虚拟机中不可直接修改,和其他C++引擎类一样可以在蓝图中继承并修改属性值。但是因为生成的C++代码需要编译,这又失去了脚本的动态优势 - 想想其实可能还好:因为无论是生成的蓝图还是C++代码,其实目的就是生成一个架子(skeleton) - 这个架子主要是成员函数的**申明**,而实际逻辑还是存在于ts脚本中...