2019-08-29 18:38:44 +08:00
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
2022-06-17 15:37:17 +08:00
#nullable disable
2019-08-29 18:38:44 +08:00
using System.Collections.Generic ;
2021-04-18 07:13:57 +08:00
using System.IO ;
2021-11-06 06:53:48 +08:00
using System.Threading ;
2019-08-29 18:38:44 +08:00
using osu.Framework.Audio.Track ;
using osu.Framework.Graphics.Textures ;
using osu.Game.Rulesets ;
using osu.Game.Rulesets.Mods ;
using osu.Game.Rulesets.Objects ;
using osu.Game.Rulesets.UI ;
using osu.Game.Skinning ;
using osu.Game.Storyboards ;
namespace osu.Game.Beatmaps
{
2021-12-22 16:44:22 +08:00
/// <summary>
2022-07-28 14:41:28 +08:00
/// A more expensive representation of a beatmap which allows access to various associated resources.
/// - Access textures and other resources via <see cref="GetStream"/>.
/// - Access the storyboard via <see cref="Storyboard"/>.
/// - Access a local skin via <see cref="Skin"/>.
/// - Access the track via <see cref="LoadTrack"/> (and then <see cref="Track"/> for subsequent accesses).
/// - Create a playable <see cref="Beatmap"/> via <see cref="GetPlayableBeatmap(osu.Game.Rulesets.IRulesetInfo,System.Collections.Generic.IReadOnlyList{osu.Game.Rulesets.Mods.Mod})"/>.
2021-12-22 16:44:22 +08:00
/// </summary>
2019-08-29 18:38:44 +08:00
public interface IWorkingBeatmap
{
2021-11-15 17:24:00 +08:00
IBeatmapInfo BeatmapInfo { get ; }
/// <summary>
/// Whether the Beatmap has finished loading.
///</summary>
2023-06-08 20:01:05 +08:00
bool BeatmapLoaded { get ; }
2021-11-15 17:24:00 +08:00
/// <summary>
/// Whether the Track has finished loading.
///</summary>
2023-06-08 20:01:05 +08:00
bool TrackLoaded { get ; }
2021-11-15 17:24:00 +08:00
2019-08-29 18:38:44 +08:00
/// <summary>
2021-11-15 17:24:00 +08:00
/// Retrieves the <see cref="IBeatmap"/> which this <see cref="IWorkingBeatmap"/> represents.
2019-08-29 18:38:44 +08:00
/// </summary>
2021-12-22 20:01:33 +08:00
IBeatmap Beatmap { get ; }
2019-08-29 18:38:44 +08:00
/// <summary>
2021-11-15 17:24:00 +08:00
/// Retrieves the background for this <see cref="IWorkingBeatmap"/>.
2019-08-29 18:38:44 +08:00
/// </summary>
2023-06-08 15:17:44 +08:00
Texture GetBackground ( ) ;
2019-08-29 18:38:44 +08:00
2023-06-08 15:30:14 +08:00
/// <summary>
/// Retrieves a cropped background for this <see cref="IWorkingBeatmap"/> used for display on panels.
/// </summary>
Revert `internal` access modifier application
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.
2023-06-08 21:18:31 +08:00
Texture GetPanelBackground ( ) ;
2023-06-08 15:30:14 +08:00
2019-08-29 18:38:44 +08:00
/// <summary>
2021-11-15 17:24:00 +08:00
/// Retrieves the <see cref="Waveform"/> for the <see cref="Track"/> of this <see cref="IWorkingBeatmap"/>.
2019-08-29 18:38:44 +08:00
/// </summary>
Waveform Waveform { get ; }
/// <summary>
2021-11-15 17:24:00 +08:00
/// Retrieves the <see cref="Storyboard"/> which this <see cref="IWorkingBeatmap"/> provides.
2019-08-29 18:38:44 +08:00
/// </summary>
Storyboard Storyboard { get ; }
/// <summary>
2021-11-15 17:24:00 +08:00
/// Retrieves the <see cref="Skin"/> which this <see cref="IWorkingBeatmap"/> provides.
2019-08-29 18:38:44 +08:00
/// </summary>
2021-12-22 20:01:33 +08:00
ISkin Skin { get ; }
2021-04-20 07:35:41 +08:00
/// <summary>
2021-11-15 17:24:00 +08:00
/// Retrieves the <see cref="Track"/> which this <see cref="IWorkingBeatmap"/> has loaded.
2021-04-20 07:35:41 +08:00
/// </summary>
2021-12-22 20:01:33 +08:00
Track Track { get ; }
2019-08-29 18:38:44 +08:00
2021-11-21 00:23:55 +08:00
/// <summary>
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
/// <para>
/// The returned <see cref="IBeatmap"/> is in a playable state - all <see cref="HitObject"/> and <see cref="BeatmapDifficulty"/> <see cref="Mod"/>s
/// have been applied, and <see cref="HitObject"/>s have been fully constructed.
/// </para>
/// </summary>
/// <remarks>
/// By default, the beatmap load process will be interrupted after 10 seconds.
/// For finer-grained control over the load process, use the
/// <see cref="GetPlayableBeatmap(osu.Game.Rulesets.IRulesetInfo,System.Collections.Generic.IReadOnlyList{osu.Game.Rulesets.Mods.Mod},System.Threading.CancellationToken)"/>
/// overload instead.
/// </remarks>
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
2021-12-22 20:01:33 +08:00
IBeatmap GetPlayableBeatmap ( IRulesetInfo ruleset , IReadOnlyList < Mod > mods = null ) ;
2021-11-21 00:23:55 +08:00
2019-08-29 18:38:44 +08:00
/// <summary>
/// Constructs a playable <see cref="IBeatmap"/> from <see cref="Beatmap"/> using the applicable converters for a specific <see cref="RulesetInfo"/>.
/// <para>
/// The returned <see cref="IBeatmap"/> is in a playable state - all <see cref="HitObject"/> and <see cref="BeatmapDifficulty"/> <see cref="Mod"/>s
/// have been applied, and <see cref="HitObject"/>s have been fully constructed.
/// </para>
/// </summary>
/// <param name="ruleset">The <see cref="RulesetInfo"/> to create a playable <see cref="IBeatmap"/> for.</param>
/// <param name="mods">The <see cref="Mod"/>s to apply to the <see cref="IBeatmap"/>.</param>
2021-11-21 00:23:55 +08:00
/// <param name="cancellationToken">Cancellation token that cancels the beatmap loading process.</param>
2019-08-29 18:38:44 +08:00
/// <returns>The converted <see cref="IBeatmap"/>.</returns>
/// <exception cref="BeatmapInvalidForRulesetException">If <see cref="Beatmap"/> could not be converted to <paramref name="ruleset"/>.</exception>
2021-11-21 00:23:55 +08:00
IBeatmap GetPlayableBeatmap ( IRulesetInfo ruleset , IReadOnlyList < Mod > mods , CancellationToken cancellationToken ) ;
2020-08-07 21:31:41 +08:00
/// <summary>
2020-08-22 18:42:34 +08:00
/// Load a new audio track instance for this beatmap. This should be called once before accessing <see cref="Track"/>.
/// The caller of this method is responsible for the lifetime of the track.
2020-08-07 21:31:41 +08:00
/// </summary>
2020-08-22 18:42:34 +08:00
/// <remarks>
/// In a standard game context, the loading of the track is managed solely by MusicController, which will
2021-11-15 17:24:00 +08:00
/// automatically load the track of the current global IBindable IWorkingBeatmap.
2020-08-22 18:42:34 +08:00
/// As such, this method should only be called in very special scenarios, such as external tests or apps which are
/// outside of the game context.
/// </remarks>
/// <returns>A fresh track instance, which will also be available via <see cref="Track"/>.</returns>
2020-08-17 14:38:16 +08:00
Track LoadTrack ( ) ;
2021-04-18 07:13:57 +08:00
2021-04-20 08:28:38 +08:00
/// <summary>
/// Returns the stream of the file from the given storage path.
/// </summary>
/// <param name="storagePath">The storage path to the file.</param>
2021-12-22 20:01:33 +08:00
Stream GetStream ( string storagePath ) ;
2021-11-15 17:24:00 +08:00
/// <summary>
/// Beings loading the contents of this <see cref="IWorkingBeatmap"/> asynchronously.
/// </summary>
2023-06-08 20:01:05 +08:00
void BeginAsyncLoad ( ) ;
2021-11-15 17:24:00 +08:00
/// <summary>
/// Cancels the asynchronous loading of the contents of this <see cref="IWorkingBeatmap"/>.
/// </summary>
2023-06-08 20:01:05 +08:00
void CancelAsyncLoad ( ) ;
2021-11-15 17:24:00 +08:00
/// <summary>
/// Reads the correct track restart point from beatmap metadata and sets looping to enabled.
/// </summary>
2022-10-12 13:46:35 +08:00
void PrepareTrackForPreview ( bool looping , double offsetFromPreviewPoint = 0 ) ;
2019-08-29 18:38:44 +08:00
}
}