Skip to content

Subclass Value Types #45

@ds5678

Description

@ds5678

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions