Wanting to use this inside notification, it turns out that the original
design did not work very well at such narrow widths, and additionally
the typical button setup borrowed from elsewhere resulted in teeny tiny
action buttons.
To that end, slim down the design (get rid of thumbnail, audio preview,
make expandable right side slimmer), as well as change the entire panel
so that it has only one action associated with it at all times, and
clicking the panel in any place triggers that action.
`ModelBackedDrawable<T>.CreateDrawable()` is R#-annotated to accept
a potentially null model. Apply nullability there too for better reading
experience.
Unfortunately breaks a few classes (which is fixable), and also breaks
Moq/Castle dynamic proxies (which is unfortunate).
Relevant error:
System.TypeLoadException : Method 'GetPanelBackground' in type 'Castle.Proxies.IWorkingBeatmapProxy' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' does not have an implementation.
Stack Trace:
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()
at Castle.DynamicProxy.Generators.BaseInterfaceProxyGenerator.GenerateType(String typeName, INamingScope namingScope)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.<>c__DisplayClass13_0.<GetProxyType>b__0(CacheKey cacheKey)
at Castle.Core.Internal.SynchronizedDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Castle.DynamicProxy.Generators.BaseProxyGenerator.GetProxyType()
at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options)
at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors)
at Moq.CastleProxyFactory.CreateProxy(Type mockType, IInterceptor interceptor, Type[] interfaces, Object[] arguments) in C:\projects\moq4\src\Moq\Interception\CastleProxyFactory.cs:line 50
In theory it would be possible to fix this via application of
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
onto the `osu.Game` assembly, but I think this would be bad precedent.
This is an effort to improve general performance at song select. At
least on the metal renderer, I can notice very high draw frame overheads
related to texture uploads.
By reducing the size of the texture uploads to roughly match what is
actually being displayed on screen (using a relatively inexpensive crop
operation), we can bastly reduce stuttering both during initial load and
carousel scroll.
You might ask if it's safe to disable mipmapping, but I've tested with
lower resolutions and bilinear filtering seems to handle just fine.
Bilinear without mipmaps only falls apart when you scale below 50% and
we're not going too far past that at minimum game scale, if at all.
Because the online info reset (which includes online ID reset) was
happening after encoding,
`TestSceneBeatmapLeaderboard.TestLocalScoresDisplayOnBeatmapEdit()`
started failing, as the hash no longer matched expectations after the
first save of the map.
this makes it easier to edit hitsounds in the stable editor after export because the sample control point effects wont get overwritten by the properties of the hitobject