osu-framework icon indicating copy to clipboard operation
osu-framework copied to clipboard

Allow value types to be cached and injected as dependencies

Open smoogipoo opened this issue 1 year ago • 5 comments

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:

  • CancellationToken is 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.

smoogipoo avatar Jan 29 '24 08:01 smoogipoo

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?

bdach avatar Feb 07 '24 13:02 bdach

Sourcegen won't need updates; I just forgot to update a test. Will get to it.

smoogipoo avatar Feb 07 '24 15:02 smoogipoo

Reading the OP:

Cache<int?>(0);                // Warning in NRT contexts

Why would this warn? Looks like perfectly legal code to me...

bdach avatar Feb 10 '24 15:02 bdach

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.

smoogipoo avatar Feb 13 '24 08:02 smoogipoo

Almost thinking all of these tests need to be rewritten...

smoogipoo avatar Feb 13 '24 08:02 smoogipoo