Skip to content

Introduce type-safe Flags and FlagArray to no longer use raw ints#186

Merged
elect86 merged 3 commits intokotlin-graphics:1.89.2from
kyay10:1.89.2
Apr 13, 2023
Merged

Introduce type-safe Flags and FlagArray to no longer use raw ints#186
elect86 merged 3 commits intokotlin-graphics:1.89.2from
kyay10:1.89.2

Conversation

@kyay10
Copy link
Copy Markdown
Collaborator

@kyay10 kyay10 commented Apr 2, 2023

This is quite a big refactoring...

Building on the previous work of using a Flag interface, this PR changes all the XFlags type aliases from being Int to being Flag<XFlags>. That, combined with a private value class Flags and a value class FlagArray, allows using type-safe flag combinations everywhere, while still having the ever-useful and, or, wo, has, etc methods.

While implementing this, I genuinely found multiple places where the code was using the wrong enum type of Flag or was checking if flags of totally separate types were equal. It was hence helpful in catching those bugs and remedying them quickly. This also removed a lot of unnecessary range checks we were doing on ints.

The only downside of using this PR is that checking flags for equality using == and != is broken. This is because you can't override equals in enums nor in value classes. For now, I added infix fun eq/notEq to mitigate that problem. However, a more intrusive solution (that will fix == checks) is to convert all the Flag enums to sealed classes (This is simply an IDE intention and so it's very automatic) with a base class that has equals overridden, and change value class Flags to a non-value class. Note that in Kotlin 1.9.0 value classes will be able to override equals. I'm not sure whether the current eq/notEq approach is too finicky, but it surely is less error-prone than comparing raw Ints.

Finally, this PR also introduces a useful MutableReference type that extends KMutableProperty0. That type might be the beginning of relying less on global mutable vars like _b and friends, and instead created MutableReferences locally., but that shall come in another PR.

@kyay10 kyay10 requested a review from elect86 April 2, 2023 00:49
@kyay10 kyay10 changed the title Introduce type-safe Flags and FlagArray to no longer use ints Introduce type-safe Flags and FlagArray to no longer use raw ints Apr 2, 2023
kyay10 added 2 commits April 3, 2023 14:37
- Remove Flag.eq and Flag.notEq and instead override equals
- Introduce val emptyFlags
- Make Flag's Self type parameter covariant
- Use kotlin.internal.NoInfer for has, hasnt, and contains to ensure that they aren't called on flags that can't possibly have those sub-flags.
- Replace assertions on flag parameters with type-safe sealed subclasses
@elect86 elect86 merged commit 0c65ed8 into kotlin-graphics:1.89.2 Apr 13, 2023
@elect86
Copy link
Copy Markdown
Collaborator

elect86 commented Apr 13, 2023

Awesome, thanks!

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

Successfully merging this pull request may close these issues.

2 participants