| | | 1 | | namespace Chronicis.Client.Services; |
| | | 2 | | |
| | | 3 | | /// <summary> |
| | | 4 | | /// Service for coordinating quest drawer toggle events and mutual exclusivity with metadata drawer. |
| | | 5 | | /// Ensures only one drawer is open at a time. |
| | | 6 | | /// Implements IDisposable to properly clean up event subscriptions. |
| | | 7 | | /// </summary> |
| | | 8 | | public class QuestDrawerService : IQuestDrawerService, IDisposable |
| | | 9 | | { |
| | | 10 | | private readonly IMetadataDrawerService _metadataDrawerService; |
| | | 11 | | private bool _isOpen; |
| | | 12 | | private bool _isProcessingMutualExclusivity; |
| | | 13 | | private bool _disposed; |
| | | 14 | | |
| | | 15 | | public event Action? OnOpen; |
| | | 16 | | public event Action? OnClose; |
| | | 17 | | |
| | 12 | 18 | | public bool IsOpen => _isOpen; |
| | | 19 | | |
| | 16 | 20 | | public QuestDrawerService(IMetadataDrawerService metadataDrawerService) |
| | | 21 | | { |
| | 16 | 22 | | _metadataDrawerService = metadataDrawerService; |
| | | 23 | | |
| | | 24 | | // Subscribe to metadata drawer toggle to ensure mutual exclusivity |
| | 16 | 25 | | _metadataDrawerService.OnToggle += OnMetadataDrawerToggled; |
| | 16 | 26 | | } |
| | | 27 | | |
| | | 28 | | public void Open() |
| | | 29 | | { |
| | 13 | 30 | | if (_disposed || _isOpen || _isProcessingMutualExclusivity) |
| | 3 | 31 | | return; |
| | | 32 | | |
| | 10 | 33 | | _isProcessingMutualExclusivity = true; |
| | | 34 | | try |
| | | 35 | | { |
| | 10 | 36 | | _isOpen = true; |
| | 10 | 37 | | OnOpen?.Invoke(); |
| | 2 | 38 | | } |
| | | 39 | | finally |
| | | 40 | | { |
| | 10 | 41 | | _isProcessingMutualExclusivity = false; |
| | 10 | 42 | | } |
| | 10 | 43 | | } |
| | | 44 | | |
| | | 45 | | public void Close() |
| | | 46 | | { |
| | 6 | 47 | | if (_disposed || !_isOpen) |
| | 3 | 48 | | return; |
| | | 49 | | |
| | 3 | 50 | | _isOpen = false; |
| | 3 | 51 | | OnClose?.Invoke(); |
| | 1 | 52 | | } |
| | | 53 | | |
| | | 54 | | public void Toggle() |
| | | 55 | | { |
| | 6 | 56 | | if (_disposed) |
| | 1 | 57 | | return; |
| | | 58 | | |
| | 5 | 59 | | if (_isOpen) |
| | 2 | 60 | | Close(); |
| | | 61 | | else |
| | 3 | 62 | | Open(); |
| | 3 | 63 | | } |
| | | 64 | | |
| | | 65 | | private void OnMetadataDrawerToggled() |
| | | 66 | | { |
| | | 67 | | // If metadata drawer is toggled while quest drawer is open, close quest drawer |
| | | 68 | | // to ensure mutual exclusivity |
| | 2 | 69 | | if (_isOpen && !_isProcessingMutualExclusivity && !_disposed) |
| | | 70 | | { |
| | 1 | 71 | | _isOpen = false; |
| | 1 | 72 | | OnClose?.Invoke(); |
| | | 73 | | } |
| | 2 | 74 | | } |
| | | 75 | | |
| | | 76 | | public void Dispose() |
| | | 77 | | { |
| | 24 | 78 | | if (_disposed) |
| | 8 | 79 | | return; |
| | | 80 | | |
| | 16 | 81 | | _disposed = true; |
| | | 82 | | |
| | | 83 | | // Unsubscribe from metadata drawer events to prevent memory leaks |
| | 16 | 84 | | _metadataDrawerService.OnToggle -= OnMetadataDrawerToggled; |
| | | 85 | | |
| | | 86 | | // Clear event handlers |
| | 16 | 87 | | OnOpen = null; |
| | 16 | 88 | | OnClose = null; |
| | | 89 | | |
| | 16 | 90 | | GC.SuppressFinalize(this); |
| | 16 | 91 | | } |
| | | 92 | | } |