1
0

JukeboxBoundUserInterface.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using Content.Shared.Audio.Jukebox;
  2. using Robust.Client.Audio;
  3. using Robust.Client.UserInterface;
  4. using Robust.Shared.Audio.Components;
  5. using Robust.Shared.Prototypes;
  6. namespace Content.Client.Audio.Jukebox;
  7. public sealed class JukeboxBoundUserInterface : BoundUserInterface
  8. {
  9. [Dependency] private readonly IPrototypeManager _protoManager = default!;
  10. [ViewVariables]
  11. private JukeboxMenu? _menu;
  12. public JukeboxBoundUserInterface(EntityUid owner, Enum uiKey) : base(owner, uiKey)
  13. {
  14. IoCManager.InjectDependencies(this);
  15. }
  16. protected override void Open()
  17. {
  18. base.Open();
  19. _menu = this.CreateWindow<JukeboxMenu>();
  20. _menu.OnPlayPressed += args =>
  21. {
  22. if (args)
  23. {
  24. SendMessage(new JukeboxPlayingMessage());
  25. }
  26. else
  27. {
  28. SendMessage(new JukeboxPauseMessage());
  29. }
  30. };
  31. _menu.OnStopPressed += () =>
  32. {
  33. SendMessage(new JukeboxStopMessage());
  34. };
  35. _menu.OnSongSelected += SelectSong;
  36. _menu.SetTime += SetTime;
  37. PopulateMusic();
  38. Reload();
  39. }
  40. /// <summary>
  41. /// Reloads the attached menu if it exists.
  42. /// </summary>
  43. public void Reload()
  44. {
  45. if (_menu == null || !EntMan.TryGetComponent(Owner, out JukeboxComponent? jukebox))
  46. return;
  47. _menu.SetAudioStream(jukebox.AudioStream);
  48. if (_protoManager.TryIndex(jukebox.SelectedSongId, out var songProto))
  49. {
  50. var length = EntMan.System<AudioSystem>().GetAudioLength(songProto.Path.Path.ToString());
  51. _menu.SetSelectedSong(songProto.Name, (float) length.TotalSeconds);
  52. }
  53. else
  54. {
  55. _menu.SetSelectedSong(string.Empty, 0f);
  56. }
  57. }
  58. public void PopulateMusic()
  59. {
  60. _menu?.Populate(_protoManager.EnumeratePrototypes<JukeboxPrototype>());
  61. }
  62. public void SelectSong(ProtoId<JukeboxPrototype> songid)
  63. {
  64. SendMessage(new JukeboxSelectedMessage(songid));
  65. }
  66. public void SetTime(float time)
  67. {
  68. var sentTime = time;
  69. // You may be wondering, what the fuck is this
  70. // Well we want to be able to predict the playback slider change, of which there are many ways to do it
  71. // We can't just use SendPredictedMessage because it will reset every tick and audio updates every frame
  72. // so it will go BRRRRT
  73. // Using ping gets us close enough that it SHOULD, MOST OF THE TIME, fall within the 0.1 second tolerance
  74. // that's still on engine so our playback position never gets corrected.
  75. if (EntMan.TryGetComponent(Owner, out JukeboxComponent? jukebox) &&
  76. EntMan.TryGetComponent(jukebox.AudioStream, out AudioComponent? audioComp))
  77. {
  78. audioComp.PlaybackPosition = time;
  79. }
  80. SendMessage(new JukeboxSetTimeMessage(sentTime));
  81. }
  82. }