JD2022-TU1/main/tools/framework/JD.Application/Plugin/Conductor.cs

144 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using JD.Audio.SoundPlayer;
using JD.Interfaces.Player;
using JD.Interfaces.Remoting;
using JD.Remoting;
namespace JD.Application.Plugin
{
/// <summary>
/// Controls the playback into the engine (play, pause, seek, ...)
/// </summary>
public class Conductor : IPlayer
{
#region Variables
private readonly List<IPlugin> _plugins;
private float _currentLocalBeat;
private float _currentAbsoluteBeat;
private bool _playing;
private readonly SeekingGuard _seekingGuard = new SeekingGuard();
private readonly PlayerTimer _timer;
public PlayerComponents Components { get; private set; }
#endregion
#region Constructor
public Conductor(IEnumerable<IPlugin> plugins)
{
Components = new PlayerComponents(this);
_timer = new PlayerTimer(this);
_plugins = new List<IPlugin>(plugins);
UseAbsoluteTime = false; // Use Local beat as default
// Do not handle on main thread,
foreach (var plugin in _plugins)
plugin.RegisterHandler(CommandNames.GetPlayingState, OnReceivedEnginePlayingState, dispatchOnMainThread: false);
}
public Conductor(IPlugin plugin)
: this(new IPlugin[] { plugin })
{
}
public void Initialize()
{
_timer.Initialize();
}
public void Dispose()
{
_timer.Dispose();
}
#endregion
#region Properties
public float CurrentTime
{
get
{
if (UseAbsoluteTime)
{
return _currentAbsoluteBeat;
}
return _currentLocalBeat;
}
set
{
//Seek no available in AbsoluteTime
if (UseAbsoluteTime == false)
{
_seekingGuard.UserSeeksTo(value);
foreach (var plugin in _plugins)
plugin.Send(CommandNames.SetBeat, blob => blob.Push(value));
_currentLocalBeat = value;
_timer.Tick();
}
}
}
public bool UseAbsoluteTime { get; set; }
public bool Playing
{
get { return _playing; }
set
{
_playing = value;
foreach (var plugin in _plugins)
plugin.Send(CommandNames.SetIsPlaying, blob => blob.Push(_playing));
}
}
#endregion
#region Methods
private bool _receivedPlaying = false;
private void OnReceivedEnginePlayingState(IBlob blob)
{
if (!_receivedPlaying)
{
_receivedPlaying = true;
float current;
float absoluteStartBeat;
float playSpeed;
blob.Extract(out _playing);
blob.Extract(out current);
blob.Extract(out absoluteStartBeat);
blob.Extract(out playSpeed);
if (_seekingGuard.IsValidEngineTime(current))
{
_currentLocalBeat = current;
_currentAbsoluteBeat = absoluteStartBeat + current;
}
_receivedPlaying = false;
}
// Do not raise the current time changed, will be called from
// the timer which is invoked from the main thread.
}
#endregion
#region Events
public event EventHandler<EventArgs> TimeChanged
{
add { _timer.TimeChanged += value; }
remove { _timer.TimeChanged -= value; }
}
#endregion
}
}