using System;
using System.Collections.Generic;
using System.Linq;
using TeamAAS.Global.Devices;
namespace TeamAAS.Motion.Motions
{
///
/// 主从会话:仅在单独驱动某条主轴时挂上从轴;其它运动先解除。
///
internal interface IMasterFollowHost
{
void BeginSoloMasterFollow(int masterAxisNo, IEnumerable slaves);
void ReleaseMasterFollow();
IDisposable SuspendFollowRelease();
}
internal sealed class MasterFollowSession
{
private int _master = -1;
private readonly List _slaves = new List();
private int _suspend;
private bool _releasing;
public int ActiveMaster => _master;
public bool Suspended => _suspend > 0;
public bool IsReleasing => _releasing;
public IDisposable Suspend()
{
_suspend++;
return new Releaser(() =>
{
if (_suspend > 0) _suspend--;
});
}
public void Begin(int masterAxisNo, IEnumerable slaves)
{
if (masterAxisNo != _master)
Release();
_master = masterAxisNo;
_slaves.Clear();
if (slaves == null) return;
foreach (var s in slaves)
{
if (s == null) continue;
if (!s.IsEnabled) s.Enable();
_slaves.Add(s);
}
}
public void Release()
{
if (_releasing || _master < 0) return;
_releasing = true;
try
{
foreach (var s in _slaves.ToList())
{
try { s.Stop(); } catch { }
}
}
finally
{
_master = -1;
_slaves.Clear();
_releasing = false;
}
}
public void Clear()
{
_master = -1;
_slaves.Clear();
_suspend = 0;
_releasing = false;
}
private sealed class Releaser : IDisposable
{
private Action _onDispose;
public Releaser(Action onDispose) => _onDispose = onDispose;
public void Dispose()
{
_onDispose?.Invoke();
_onDispose = null;
}
}
}
}