Git Product home page Git Product logo

tsu's People

Contributors

mihe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tsu's Issues

Exported functions can't be async

async functions return promises, which there's currently no support for.

It would be neat if exported async functions were somehow translated into latent nodes in Blueprint, like Delay.

Can't import other TypeScript files without compiling them first

If you want to import a file that isn't a "TBP file", or you can't/won't use the import { TBP_Foo } from 'UE/TBP_Foo' syntax, then you're currently forced to continously compile the TypeScript file to JavaScript.

It would be nice to somehow get rid of this requirement and only ever deal with TypeScript files, kinda like ts-node.

Starting the editor becomes prohibitively slow with many scripts

Since the TSU blueprints currently get compiled when you start the editor it can bump up the startup time for the editor quite a bit. There should ideally not be any reason at all to parse the TypeScript since it should all be baked into the .uasset.

The only thing I could see being a problem is if the generated typings were to change, in which case the TypeScript code should be reparsed and produce an error if faulty.

If recompiling on startup turns out to be unavoidable there's also the new .tsbuildinfo stuff that was released with TypeScript 3.4, which should cut the initial compile times down significantly.

Some number parameters/properties get truncated

Due to JavaScript/TypeScript not really having a notion of an integer (outside of the recently added BigInt) it becomes a problem when you have functions like UKismetMathLibrary::Clamp, which only clamps int32.

This then shows up in the typings as:

static clamp(value: number, min: number, max: number): number;

... which looks harmless but will in fact truncate any decimals that gets sent into it. Outside of looking at the actual C++ declaration of the target function there is no way of knowing if something will truncate or not.

I'm not sure how to fix this, but one alternative would be to at least emit some kind of documentation, like:

/**
 * @param value Warning: Integer parameter, will truncate
 * @param min Warning: Integer parameter, will truncate
 * @param max Warning: Integer parameter, will truncate
 */
 static clamp(value: number, min: number, max: number): number;

Can't poll or listen to input mappings

With #12 being fixed you can now do stuff like controller.isInputKeyDown(EKeys.SpaceBar), but you still can't poll or listen to input mappings.

I still don't how to do this one, at all. I was hoping to leverage the UInputDelegateBinding stuff that Blueprint itself uses, but it seems so tightly bound to only work with their internal types that I can't piggyback on it, regardless of what hacks I try to employ.

The C++ way of using input mappings involves overriding APawn::SetupPlayerInputComponent, which obviously isn't possible from just static functions.

I can't really see a small-ish change to UE4 that Epic would be happy to integrate either, but if anyone has any ideas then I'm all ears.

Not available for Linux

For a start it's gonna involve getting a Linux version of V8, TsuParser and FTsuReplProcess up and running. Might have some overlap with #22.

Also keep in mind that Win64 is currently the only whitelisted platform in TSU.uplugin.

Blueprint dependencies don't load

It seems UBlueprint::GatherDependencies isn't doing the trick of signaling to UE4 that certain TSU blueprints are dependant on other blueprints.

If a certain blueprint is only used within TSU code, and not as a parameter type or return type, then it seems those blueprints never get loaded, causing an error when the dependant code tries to import it.

I've tried using LoadObject instead of FindObject in FTsuTypeIndex::Find, but that results in the context resetting itself (due to OnBlueprintPreCompile) while we're inside a V8 callback, which is not great.

There has to be some other proper way to signal which blueprints is depended on.

Not available for macOS

For a start it's gonna involve getting a macOS version of V8, TsuParser and FTsuReplProcess up and running.

Also keep in mind that Win64 is currently the only whitelisted platform in TSU.uplugin.

Exceptions don't log stack traces

Currently exceptions produce something along these lines:

LogTsuRuntime: Error: [V8] Uncaught TypeError: Cannot set property 'test' of undefined
LogTsuRuntime: Error:     at Saucer/TBP_Saucer.js:19:21

... which comes from FTsuTryCatch.

Ideally this should produce some sort of call stack, and also make use of source-map-support in order to get the real file name and line numbers from the inlined source maps.

"Add [...] Component" nodes aren't exposed

These seem to be handled in blueprint through UK2Node_AddComponent.

The current workaround would be something similar to how it is in C++:

export function construct(target: BP_Foo, mesh: StaticMesh) {
    const component = new StaticMeshComponent(target);
    component.registerComponent();
    component.setStaticMesh(mesh);
    target.addOwnedComponent(component);
}

Unknown types always become UObject

Trying to do something like:

export function(param: {}) { /* ... */ }

... will result in param resolving to a UObject pin in the resulting blueprint function.

This is because FTsuTypeIndex::Find is too aggressive right now, and will turn any unknown/unresolvable type into UObject.

It was made to be that way because of prior issues with blueprint types randomly failing to resolve, and instead of just throwing that pin away it was made to fall back on UObject instead, which would still allow any dependant blueprints to compile.

One potential fix would be to have the parser server report if the type is a derivative of UObject and only fall back to UObject if that's the case.

Reference parameters are treated as output parameters

Parameters with the UPARAM(ref) annotation currently gets treated as an output parameter, which results in some janky typings, like:

declare class Vector2D {
    normalize(tolerance?: number): { a: Vector2D };
}

It should instead perform the operation in-place and not return anything.

Some preliminary tests with simply excluding CPF_ReferenceParm from FTsuReflection::IsOutputParameter didn't seem to work. The actual invocation probably needs to not copy the value if it's a reference parameter or something.

Can't return multiple values back to Blueprint

Currently there's no way to return multiple things back to Blueprint, which is usually done in by returning an object with an entry for each return value, like so:

export function getBounds(target: Actor) {
    const origin: Vector = /* ... */;
    const extents: Vector = /* ... */;
    return { origin, extents };
}

... which would then ideally get translated into a Blueprint node with an output pin for both Origin and Extents.

Nullability in typings is wrong

Currently only input reference parameters are nullable (i.e. marked as | null). This was added as a hack in order to allow null to be passed to function parameters while having strictNullChecks enabled.

This problem still applies to reference properties though, and with properties not being nullable you currently can't set them to null with strictNullChecks enabled.

The naive solution would be to simply make every reference property nullable as well. However, this makes them way too tiresome to work with, because you end up sprinkling non-null assertions and unnecessary if-statements all over your code. The biggest source of this comes from actor components also being marked as nullable, when in reality they will never be null (in Blueprint classes at least).

A more refined solution would therefore try to figure out if a reference property is in fact an actor component and leave out nullability. However, regular reference properties to actor components or references to actor component declared in C++ can't have the same non-null guarantee and would therefore still have to be nullable.

All-in-all it's messy whichever way you look at it, because the typings are generated from a type system that doesn't express nullability.

I'm leaning towards simply scrapping nullability from the typings entirely and discouraging the use of strictNullChecks.

Errors in VS Code's debug console

When debugging using VS Code you sometimes get errors saying:

Error evaluating `process.pid`: Cannot find context with specified id

It might have something to do with missing or incorrectly implementing parts of the v8_inspector::V8InspectorClient implementation.

"Failed to bind native function" warnings

Tons of warnings like these ones show up when starting the editor:

LogClass: Warning: Failed to bind native function REINST_TBP_Something_C_5.someFunction
LogClass: Warning: Failed to bind native function TRASHCLASS_TBP_Something_25.someFunction

Editor freezes from module-scope exceptions

Module-scope exceptions can potentially result in some/all functions not being exported, which will make FTsuContext::Invoke abort early and cause Stack.Code to never move, resulting in UObject::ProcessInternal getting stuck on while (*Stack.Code != EX_Return).

Can't extend typings with constants

There's no way to represent things like FVector::ZeroVector, FRotator::ZeroRotator or FTransform::Identity.

Ideally these should somehow be provided as a static readonly properties on each respective class.

Setting up a new project is tedious and error-prone

Right now you have to jump through a lot of hoops in order to setup a new project. Any reduction in the number of steps would be a good thing.

Ideally the plugin would ship with a project template. The biggest problem with that is that it requires the plugin to first of all be installed into the engine plugins (like Marketplace ones do), and also that it's enabled by default, which currently makes it generate a bunch of typings into %LOCALAPPDATA%\UnrealEngine\4.21\Intermediate.

Can't provide static extension methods

Currently there's no way to extend typings with new static methods.

There needs to be some way to disambiguate cases like:

UFUNCTION(BlueprintPure)
static float Triple(FVector X, FVector Y, FVector Z);

... where the current way of doing things would translate it to:

declare class Vector {
    triple(y: Vector, z: Vector): number;
}

... and instead have it be:

declare class Vector {
    static triple(x: Vector, y: Vector, z: Vector): number;
}

Doesn't compile in non-editor builds

Right now there are a few issues preventing TSU from compiling in non-editor builds:

  1. UField metadata used for marshaling (GetMetaData, HasMetaData, etc).
  2. FFileHelper::LoadFileToString for require (self-imposed restriction).
  3. Exception handling used in TsuInspectorClient.cpp.

The respective solutions to these would be something like:

  1. Replace the current marshaling of native stuff with generated code, through TsuGenerator.
  2. Make require a part of some V8 startup snapshot.
  3. Move the inspector stuff to TsuEditor, or replace WebSocket++ with libwebsocket.

There's probably gonna be more issues down the line as well.

Typings don't get updated when adding exports in a hot reload

Which is because we defer compilations until after the play session is over, and instead only reload the context.

The only possible fix for this would be to somehow compile the UTsuBlueprint during a play session, which I don't think is even possible.

Not available for Win32

Should hopefully just be a matter of shipping a Win32 version of TsuParser and V8.

Also keep in mind that Win64 is currently the only whitelisted platform in TSU.uplugin.

Custom events aren't exposed

Custom events defined in a blueprint are callable from other blueprints, but can't be called from TypeScript.

I'm not sure if this is possible at all, but it feels like something that would be nice to have.

Easing functions are not exposed

For whatever reason the easing functions in UKismetMathLibrary were marked as BlueprintInternalUseOnly and instead dynamically chosen through the custom Blueprint node UK2Node_EaseFunction. This has the unfortunate consequence of the easing functions not being exposed in the typings.

Either we give those functions special treatment and let them get exposed despite being BlueprintInternalUseOnly, or we add something like TsuMathLibrary. Alternatively if #3 gets solved they could get added as extensions to UKismetMathLibrary.

Add build instructions for V8

Ideally there would be some script(s) bundled with the repo that downloads the currently targeted version of V8 and builds it for some/all platforms. If not, then at least some instructions on how to build a component (DLL) build of V8.

Function nodes sometimes gets replaced

If you start the editor and a script for whatever reason doesn't parse/compile then calls that are using functions from it can sometimes mysteriously get replaced with calls to similar named functions. This is due to some code inside K2Node_CallFunction.cpp that explicitly does this for function libraries.

Might be worthwile to submit a PR that lets you disable this functionality somehow.

Can't get input values

Things like procedurally getting axis/button values, either through the designated getter node generated from the input mapping, or through APlayerController::IsInputKeyDown.

Ideally there would be typings generated based on the input mapping or something.

Can't import other TypeScript files without compiling them

Importing other TypeScript files, whether it's other TSU files or just utility files, need to be compiled down to .js files first, which quickly becomes tedious and error-prone. It would be nice if this could be solved in some way.

The current workaround for importing other TSU files is to import them using the UE/ prefix, like:

import * as Thing from 'UE/TBP_Thing';

Functions using parameters of internal types don't get exposed

Any function with a parameter of a type marked as BlueprintInternalUseOnly will currently not get exposed at all.

This includes any asynchronous functions like UKismetSystemLibrary::Delay or UGameplayStatics::LoadStreamLevel.

This is deliberately so until I can figure out how to deal with the FLatentActionInfo stuff.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.