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; } } } }