Update Tensor types, for accuracy #15053
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR changes types on the Tensor API to be more accurate. The changes are described in more detail below.
Note:
Class
is used in place of some class in the Tensor API1.
this
vsClass
In the example,
T extends this
andDeepImmutable<this>
are inaccurate. The method does not need the arguments to bethis
, only that they areClass
. When I was originally creating the Tensor API, I usedthis
out of convenience. Doing so has caused several problems.Using
this
instead ofClass
makes the type more strict. This is not needed with the Tensor API classes because they are compatible wthClass
, not justthis
. The PR changesthis
toClass
wherethis
is not needed. Note that the return types of functions which return the valuethis
are the typethis
.A brief example:
2. Introduction of
I
, the "interface" type, for compatibility.Recently, I've been working with shaders in GLSL. I've been amazed by the developer experience with operator overloading and thought something similar would be a huge boost for the Tensor API classes.
I noticed a significant part of the vector math functions are of the form
My line of thinking:
IClassLike
)For example, with
Vector4
:Which can then be used like
vec2.addInPlace(vec4)
. Note that this will not work forvec3.*(vec4)
since theVector3
functions use the internal_x
/_y
/_z
, which are not used byVector2
andVector4
.In addition, when adding a vector of lower dimension, like
vec4.add(vec2)
, some coordinates may be set toNaN
. This is reflected in the types. For example,vec4.*
will only take anIVector4Like
, soIVector2Like
will give an error. While adding|| 0
to the end of many operations would fix this simple issue, I have not done so due to performance concerns.3. Overengineered:
(value.constructor as Constructor<typeof Class, T>)
(value.constructor as Constructor<typeof Class, T>)
is an incredibly verbose statement, which unnecessarily complicates things. UsingClass
instead makes the code much more readable, and provides a minor performance boost, since there is a single variable access (i.e.Class
) instead of a variable access followed by a property lookup, which also involves the value prototype.