osu-framework
osu-framework copied to clipboard
Allow value types to be cached and injected as dependencies
Resolves https://github.com/ppy/osu-framework/issues/6157
Consider this an RFC.
The way structs are handled right now is a mess. If I (as the person who wrote all of this) can't understand how they're handled, then I don't think anyone can. And my confusion is the result of two conflicting thought processes:
CancellationTokenis somehow a special type. How is it so?- The way I view structs is as always being initialised, whether in a "zeroed" state or otherwise (unless they're nullable).
Every value type is a special type that can only be cached by osu!framework. CancellationToken is doubly special because it sometimes arrives in load(), and sometimes doesn't, depending on whether you're in an async-load context. So the only proper way to use BDL with CancellationToken is to make it nullable.
In my opinion, if you want to cache and resolve a value-type dependency and accept whatever footguns that comes with (by-val copies, you can't cache multiple ints, etc), then you should be able to do so. But the framework should retain predictable semantics, which for me means matching the C# spec - ValueType = default! is a zero-initialised struct. This is a simplification of semantics to me.
New semantics:
Get<int>() => 0; // Allowed
Get<int?>() => null; // Allowed
Cache<int>(0); // Allowed
Cache<int>(null); // Disallowed
Cache<int?>(0); // Warning in NRT contexts
CacheAs<IInterface>(MyStruct); // Allowed - boxed.
Cache<object>(null); // Exception
Cache<object?>(null); // Exception + warning in NRT contexts
Is this something I foresee being used? No. It's just for the sake of clarifying semantics.
Why are tests failing here? I'd expect failures in the sourcegen path until a package bump or something, but the reflection path is failing too?
Sourcegen won't need updates; I just forgot to update a test. Will get to it.
Reading the OP:
Cache<int?>(0); // Warning in NRT contexts
Why would this warn? Looks like perfectly legal code to me...
Why would this warn? Looks like perfectly legal code to me...
Because caching null is not allowed 1 2, therefore attempting to cache a may-be-null value warns about that.
Almost thinking all of these tests need to be rewritten...