// 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. using System; using osu.Framework.Allocation; using osu.Framework.Audio.Track; using osu.Framework.Graphics; using osu.Framework.Threading; namespace osu.Game.Audio { [LongRunningLoad] public abstract class PreviewTrack : Component { /// <summary> /// Invoked when this <see cref="PreviewTrack"/> has stopped playing. /// Not invoked in a thread-safe context. /// </summary> public event Action Stopped; /// <summary> /// Invoked when this <see cref="PreviewTrack"/> has started playing. /// Not invoked in a thread-safe context. /// </summary> public event Action Started; protected Track Track { get; private set; } private bool hasStarted; [BackgroundDependencyLoader] private void load() { Track = GetTrack(); if (Track != null) Track.Completed += Stop; } /// <summary> /// Length of the track. /// </summary> public double Length => Track?.Length ?? 0; /// <summary> /// The current track time. /// </summary> public double CurrentTime => Track?.CurrentTime ?? 0; /// <summary> /// Whether the track is loaded. /// </summary> public bool TrackLoaded => Track?.IsLoaded ?? false; /// <summary> /// Whether the track is playing. /// </summary> public bool IsRunning => Track?.IsRunning ?? false; private ScheduledDelegate startDelegate; /// <summary> /// Starts playing this <see cref="PreviewTrack"/>. /// </summary> /// <returns>Whether the track is started or already playing.</returns> public bool Start() { if (Track == null) return false; startDelegate = Schedule(() => { if (hasStarted) return; hasStarted = true; Track.Restart(); Started?.Invoke(); }); return true; } /// <summary> /// Stops playing this <see cref="PreviewTrack"/>. /// </summary> public void Stop() { startDelegate?.Cancel(); if (Track == null) return; if (!hasStarted) return; hasStarted = false; Track.Stop(); Stopped?.Invoke(); } /// <summary> /// Retrieves the audio track. /// </summary> protected abstract Track GetTrack(); } }