Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subclass Value Types #45

Open
ds5678 opened this issue Oct 11, 2023 · 0 comments
Open

Subclass Value Types #45

ds5678 opened this issue Oct 11, 2023 · 0 comments

Comments

@ds5678
Copy link
Collaborator

ds5678 commented Oct 11, 2023

Context

Having reference types on the heap is somewhat expensive, both in terms of performance and memory usage. It would be nice to improve this where we can.

Proposal 1: Special case important types

Special-casing a few crucial mathematical types would provide most of the benefit for this feature.

  • Vector2f -> System.Numerics.Vector2
  • Vector3f -> System.Numerics.Vector3
  • Vector4f -> System.Numerics.Vector4
  • Vector4Float -> System.Numerics.Vector4
  • Quaternionf -> System.Numerics.Quaternion
  • Rectf -> System.Drawing.RectangleF
  • BoneWeights4 -> AssetRipper.Numerics.BoneWeight4
  • ColorRGBAf -> AssetRipper.Numerics.ColorFloat
  • ColorRGBA32 -> AssetRipper.Numerics.Color32
  • Vector2Int -> AssetRipper.Numerics.Vector2i
  • Vector3Int -> AssetRipper.Numerics.Vector3i

These types are ubiquitous and account for a substantial portion of the issue, due to their frequent use in lists.

MonoBehaviour

These classes may still need to be generated for MonoBehaviour.Structure.

Utf8String

The infrastructure for supporting these other types could be extended to Utf8String, removing its unique casing.

Proposal 2: Make version-less subclasses into structs

There could be large performance benefits to converting many of the subclasses into value types.

Here are the rules for when a subclass can be converted to a struct:

  • The subclass must be version-independent.
    • Boxing will occur whenever the interface is used, which happens often for version-dependent types.
  • All of its fields must be value types.
    • It would be easy to accidentally cause null reference exceptions if Utf8String is allowed.
    • If arrays, lists, pairs, dictionaries, or PPtrs were allowed, there would be a catch-22 situation with set methods.
  • It cannot be a PPtr.
    • PPtrs are intentionally designed so that they cannot be copied directly.

These restrictions have the following benefits:

  • default is a valid value.
  • The parameterless constructor is optional.
  • They can be used as parameters in set methods.
  • The interface could be removed.

MonoBehaviour

These structs may still need to implement IUnityAssetBase for MonoBehaviour.Structure.

Implicit Conversions

It would be convenient to have bidirectional implicit conversions for common mathematical value types.

Some conversions can be done purely with Unsafe.As since the types would contain the same memory layout:

  • Vector2f <-> System.Numerics.Vector2
  • Vector3f <-> System.Numerics.Vector3
  • Vector4f <-> System.Numerics.Vector4
  • Vector4Float <-> System.Numerics.Vector4
  • Quaternionf <-> System.Numerics.Quaternion
  • Vector2f <-> System.Drawing.PointF
  • Vector2Int <-> System.Drawing.Point
  • Vector2f <-> System.Drawing.SizeF
  • Vector2Int <-> System.Drawing.Size
  • Rectf <-> System.Drawing.RectangleF
  • RectInt <-> System.Drawing.Rectangle
  • BoneWeights4 <-> AssetRipper.Numerics.BoneWeight4
  • ColorRGBAf <-> AssetRipper.Numerics.ColorFloat
  • ColorRGBA32 <-> AssetRipper.Numerics.Color32
  • Vector2Int <-> AssetRipper.Numerics.Vector2i
  • Vector3Int <-> AssetRipper.Numerics.Vector3i

Other conversions may require some small processing:

  • AABB <-> System.Drawing.RectangleF
  • AABBInt <-> System.Drawing.Rectangle
  • Matrix4x4f <-> System.Numerics.Matrix4x4

Future

Choosing this option does not rule out the possibility of later special casing a few types, as described in proposal 1.

Generic Vector Types

It's possible that AssetRipper will implement (or use from a library) generic vector types, eg Vector2<T>. If it does, some of the AssetRipper.Numerics types may be removed.

BCL proposal (not coming at least until .NET 9): dotnet/runtime#24168

Potential library: https://github.com/SparkieLabs/generic-vectors-matrices

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant