MasterFollowSession.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using TeamAAS.Global.Devices;
  5. namespace TeamAAS.Motion.Motions
  6. {
  7. /// <summary>
  8. /// 主从会话:仅在单独驱动某条主轴时挂上从轴;其它运动先解除。
  9. /// </summary>
  10. internal interface IMasterFollowHost
  11. {
  12. void BeginSoloMasterFollow(int masterAxisNo, IEnumerable<IAxis> slaves);
  13. void ReleaseMasterFollow();
  14. IDisposable SuspendFollowRelease();
  15. }
  16. internal sealed class MasterFollowSession
  17. {
  18. private int _master = -1;
  19. private readonly List<IAxis> _slaves = new List<IAxis>();
  20. private int _suspend;
  21. private bool _releasing;
  22. public int ActiveMaster => _master;
  23. public bool Suspended => _suspend > 0;
  24. public bool IsReleasing => _releasing;
  25. public IDisposable Suspend()
  26. {
  27. _suspend++;
  28. return new Releaser(() =>
  29. {
  30. if (_suspend > 0) _suspend--;
  31. });
  32. }
  33. public void Begin(int masterAxisNo, IEnumerable<IAxis> slaves)
  34. {
  35. if (masterAxisNo != _master)
  36. Release();
  37. _master = masterAxisNo;
  38. _slaves.Clear();
  39. if (slaves == null) return;
  40. foreach (var s in slaves)
  41. {
  42. if (s == null) continue;
  43. if (!s.IsEnabled) s.Enable();
  44. _slaves.Add(s);
  45. }
  46. }
  47. public void Release()
  48. {
  49. if (_releasing || _master < 0) return;
  50. _releasing = true;
  51. try
  52. {
  53. foreach (var s in _slaves.ToList())
  54. {
  55. try { s.Stop(); } catch { }
  56. }
  57. }
  58. finally
  59. {
  60. _master = -1;
  61. _slaves.Clear();
  62. _releasing = false;
  63. }
  64. }
  65. public void Clear()
  66. {
  67. _master = -1;
  68. _slaves.Clear();
  69. _suspend = 0;
  70. _releasing = false;
  71. }
  72. private sealed class Releaser : IDisposable
  73. {
  74. private Action _onDispose;
  75. public Releaser(Action onDispose) => _onDispose = onDispose;
  76. public void Dispose()
  77. {
  78. _onDispose?.Invoke();
  79. _onDispose = null;
  80. }
  81. }
  82. }
  83. }