318 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
		
		
			
		
	
	
			318 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C#
		
	
	
	
|  | namespace SRDebugger.Services.Implementation | |||
|  | { | |||
|  |     using System; | |||
|  |     using Internal; | |||
|  |     using SRF; | |||
|  |     using SRF.Service; | |||
|  |     using UnityEngine; | |||
|  |     using Object = UnityEngine.Object; | |||
|  |     using SRF.UI; | |||
|  |     using UnityEngine.UI; | |||
|  | 
 | |||
|  |     [Service(typeof (IDebugService))] | |||
|  |     public class SRDebugService : IDebugService | |||
|  |     { | |||
|  |         public IDockConsoleService DockConsole | |||
|  |         { | |||
|  |             get { return Service.DockConsole; } | |||
|  |         } | |||
|  | 
 | |||
|  |         public event VisibilityChangedDelegate PanelVisibilityChanged; | |||
|  |         public event PinnedUiCanvasCreated PinnedUiCanvasCreated; | |||
|  | 
 | |||
|  |         private readonly IDebugPanelService _debugPanelService; | |||
|  |         private readonly IDebugTriggerService _debugTrigger; | |||
|  |         private readonly ISystemInformationService _informationService; | |||
|  |         private readonly IOptionsService _optionsService; | |||
|  |         private readonly IPinnedUIService _pinnedUiService; | |||
|  | 
 | |||
|  |         private bool _entryCodeEnabled; | |||
|  |         private bool _hasAuthorised; | |||
|  |         private DefaultTabs? _queuedTab; | |||
|  |         private RectTransform _worldSpaceTransform; | |||
|  | 
 | |||
|  |         public SRDebugService() | |||
|  |         { | |||
|  |             SRServiceManager.RegisterService<IDebugService>(this); | |||
|  | 
 | |||
|  |             // Load profiler | |||
|  |             SRServiceManager.GetService<IProfilerService>(); | |||
|  | 
 | |||
|  |             // Setup trigger service | |||
|  |             _debugTrigger = SRServiceManager.GetService<IDebugTriggerService>(); | |||
|  | 
 | |||
|  |             _informationService = SRServiceManager.GetService<ISystemInformationService>(); | |||
|  | 
 | |||
|  |             _pinnedUiService = SRServiceManager.GetService<IPinnedUIService>(); | |||
|  |             _pinnedUiService.OptionsCanvasCreated += transform => | |||
|  |             { | |||
|  |                 if (PinnedUiCanvasCreated == null) return; | |||
|  |                 try | |||
|  |                 { | |||
|  |                     PinnedUiCanvasCreated(transform); | |||
|  |                 } | |||
|  |                 catch(Exception e) | |||
|  |                 { | |||
|  |                     Debug.LogException(e); | |||
|  |                 } | |||
|  |             }; | |||
|  | 
 | |||
|  |             _optionsService = SRServiceManager.GetService<IOptionsService>(); | |||
|  | 
 | |||
|  |             // Create debug panel service (this does not actually load any UI resources until opened) | |||
|  |             _debugPanelService = SRServiceManager.GetService<IDebugPanelService>(); | |||
|  | 
 | |||
|  |             // Subscribe to visibility changes to provide API-facing event for panel open/close | |||
|  |             _debugPanelService.VisibilityChanged += DebugPanelServiceOnVisibilityChanged; | |||
|  | 
 | |||
|  |             _debugTrigger.IsEnabled = Settings.EnableTrigger == Settings.TriggerEnableModes.Enabled || | |||
|  |                                       Settings.EnableTrigger == Settings.TriggerEnableModes.MobileOnly && Application.isMobilePlatform || | |||
|  |                                       Settings.EnableTrigger == Settings.TriggerEnableModes.DevelopmentBuildsOnly && Debug.isDebugBuild; | |||
|  | 
 | |||
|  |             _debugTrigger.Position = Settings.TriggerPosition; | |||
|  | 
 | |||
|  |             if (Settings.EnableKeyboardShortcuts) | |||
|  |             { | |||
|  |                 SRServiceManager.GetService<KeyboardShortcutListenerService>(); | |||
|  |             } | |||
|  | 
 | |||
|  |             _entryCodeEnabled = Settings.Instance.RequireCode && Settings.Instance.EntryCode.Count == 4; | |||
|  | 
 | |||
|  |             if (Settings.Instance.RequireCode && !_entryCodeEnabled) | |||
|  |             { | |||
|  |                 Debug.LogError("[SRDebugger] RequireCode is enabled, but pin is not 4 digits"); | |||
|  |             } | |||
|  | 
 | |||
|  |             // Ensure that root object cannot be destroyed on scene loads | |||
|  |             var srDebuggerParent = Hierarchy.Get("SRDebugger"); | |||
|  |             Object.DontDestroyOnLoad(srDebuggerParent.gameObject); | |||
|  | 
 | |||
|  |             // Add any options containers that were created on init | |||
|  |             var internalRegistry = SRServiceManager.GetService<InternalOptionsRegistry>(); | |||
|  |             internalRegistry.SetHandler(_optionsService.AddContainer); | |||
|  |         } | |||
|  | 
 | |||
|  |         public Settings Settings | |||
|  |         { | |||
|  |             get { return Settings.Instance; } | |||
|  |         } | |||
|  | 
 | |||
|  |         public bool IsDebugPanelVisible | |||
|  |         { | |||
|  |             get { return _debugPanelService.IsVisible; } | |||
|  |         } | |||
|  | 
 | |||
|  |         public bool IsTriggerEnabled | |||
|  |         { | |||
|  |             get { return _debugTrigger.IsEnabled; } | |||
|  |             set { _debugTrigger.IsEnabled = value; } | |||
|  |         } | |||
|  | 
 | |||
|  |         public bool IsProfilerDocked | |||
|  |         { | |||
|  |             get { return Service.PinnedUI.IsProfilerPinned; } | |||
|  |             set { Service.PinnedUI.IsProfilerPinned = value; } | |||
|  |         } | |||
|  | 
 | |||
|  |         public void AddSystemInfo(InfoEntry entry, string category = "Default") | |||
|  |         { | |||
|  |             _informationService.Add(entry, category); | |||
|  |         } | |||
|  | 
 | |||
|  |         public void ShowDebugPanel(bool requireEntryCode = true) | |||
|  |         { | |||
|  |             if (requireEntryCode && _entryCodeEnabled && !_hasAuthorised) | |||
|  |             { | |||
|  |                 PromptEntryCode(); | |||
|  |                 return; | |||
|  |             } | |||
|  | 
 | |||
|  |             _debugPanelService.IsVisible = true; | |||
|  |         } | |||
|  | 
 | |||
|  |         public void ShowDebugPanel(DefaultTabs tab, bool requireEntryCode = true) | |||
|  |         { | |||
|  |             if (requireEntryCode && _entryCodeEnabled && !_hasAuthorised) | |||
|  |             { | |||
|  |                 _queuedTab = tab; | |||
|  |                 PromptEntryCode(); | |||
|  |                 return; | |||
|  |             } | |||
|  | 
 | |||
|  |             _debugPanelService.IsVisible = true; | |||
|  |             _debugPanelService.OpenTab(tab); | |||
|  |         } | |||
|  | 
 | |||
|  |         public void HideDebugPanel() | |||
|  |         { | |||
|  |             _debugPanelService.IsVisible = false; | |||
|  |         } | |||
|  | 
 | |||
|  |         public void DestroyDebugPanel() | |||
|  |         { | |||
|  |             _debugPanelService.IsVisible = false; | |||
|  |             _debugPanelService.Unload(); | |||
|  |         } | |||
|  | 
 | |||
|  |         #region Options | |||
|  | 
 | |||
|  |         public void AddOptionContainer(object container) | |||
|  |         { | |||
|  |             _optionsService.AddContainer(container); | |||
|  |         } | |||
|  | 
 | |||
|  |         public void RemoveOptionContainer(object container) | |||
|  |         { | |||
|  |             _optionsService.RemoveContainer(container); | |||
|  |         } | |||
|  | 
 | |||
|  |         public void PinAllOptions(string category) | |||
|  |         { | |||
|  |             foreach (var op in _optionsService.Options) | |||
|  |             { | |||
|  |                 if (op.Category == category) | |||
|  |                 { | |||
|  |                     _pinnedUiService.Pin(op); | |||
|  |                 } | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         public void UnpinAllOptions(string category) | |||
|  |         { | |||
|  |             foreach (var op in _optionsService.Options) | |||
|  |             { | |||
|  |                 if (op.Category == category) | |||
|  |                 { | |||
|  |                     _pinnedUiService.Unpin(op); | |||
|  |                 } | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         public void PinOption(string name) | |||
|  |         { | |||
|  |             foreach (var op in _optionsService.Options) | |||
|  |             { | |||
|  |                 if (op.Name == name) | |||
|  |                 { | |||
|  |                     _pinnedUiService.Pin(op); | |||
|  |                 } | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         public void UnpinOption(string name) | |||
|  |         { | |||
|  |             foreach (var op in _optionsService.Options) | |||
|  |             { | |||
|  |                 if (op.Name == name) | |||
|  |                 { | |||
|  |                     _pinnedUiService.Unpin(op); | |||
|  |                 } | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         public void ClearPinnedOptions() | |||
|  |         { | |||
|  |             _pinnedUiService.UnpinAll(); | |||
|  |         } | |||
|  | 
 | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         #region Bug Reporter | |||
|  | 
 | |||
|  |         public void ShowBugReportSheet(ActionCompleteCallback onComplete = null, bool takeScreenshot = true, | |||
|  |             string descriptionContent = null) | |||
|  |         { | |||
|  |             var popoverService = SRServiceManager.GetService<BugReportPopoverService>(); | |||
|  | 
 | |||
|  |             if (popoverService.IsShowingPopover) | |||
|  |             { | |||
|  |                 return; | |||
|  |             } | |||
|  | 
 | |||
|  |             popoverService.ShowBugReporter((succeed, message) => | |||
|  |             { | |||
|  |                 if (onComplete != null) | |||
|  |                 { | |||
|  |                     onComplete(succeed); | |||
|  |                 } | |||
|  |             }, takeScreenshot, descriptionContent); | |||
|  |         } | |||
|  | 
 | |||
|  |         #endregion | |||
|  | 
 | |||
|  |         private void DebugPanelServiceOnVisibilityChanged(IDebugPanelService debugPanelService, bool b) | |||
|  |         { | |||
|  |             if (PanelVisibilityChanged == null) | |||
|  |             { | |||
|  |                 return; | |||
|  |             } | |||
|  | 
 | |||
|  |             try | |||
|  |             { | |||
|  |                 PanelVisibilityChanged(b); | |||
|  |             } | |||
|  |             catch (Exception e) | |||
|  |             { | |||
|  |                 Debug.LogError("[SRDebugger] Event target threw exception (IDebugService.PanelVisiblityChanged)"); | |||
|  |                 Debug.LogException(e); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         private void PromptEntryCode() | |||
|  |         { | |||
|  |             SRServiceManager.GetService<IPinEntryService>() | |||
|  |                 .ShowPinEntry(Settings.Instance.EntryCode, SRDebugStrings.Current.PinEntryPrompt, | |||
|  |                     entered => | |||
|  |                     { | |||
|  |                         if (entered) | |||
|  |                         { | |||
|  |                             if (!Settings.Instance.RequireEntryCodeEveryTime) | |||
|  |                             { | |||
|  |                                 _hasAuthorised = true; | |||
|  |                             } | |||
|  | 
 | |||
|  |                             if (_queuedTab.HasValue) | |||
|  |                             { | |||
|  |                                 var t = _queuedTab.Value; | |||
|  | 
 | |||
|  |                                 _queuedTab = null; | |||
|  |                                 ShowDebugPanel(t, false); | |||
|  |                             } | |||
|  |                             else | |||
|  |                             { | |||
|  |                                 ShowDebugPanel(false); | |||
|  |                             } | |||
|  |                         } | |||
|  | 
 | |||
|  |                         _queuedTab = null; | |||
|  |                     }); | |||
|  |         } | |||
|  | 
 | |||
|  |         public RectTransform EnableWorldSpaceMode() | |||
|  |         { | |||
|  |             if (_worldSpaceTransform != null) | |||
|  |             { | |||
|  |                 return _worldSpaceTransform; | |||
|  |             } | |||
|  | 
 | |||
|  |             if (Settings.Instance.UseDebugCamera) | |||
|  |             { | |||
|  |                 throw new InvalidOperationException("UseDebugCamera cannot be enabled at the same time as EnableWorldSpaceMode."); | |||
|  |             } | |||
|  |              | |||
|  |             _debugPanelService.IsVisible = true; | |||
|  | 
 | |||
|  |             var root = ((DebugPanelServiceImpl) _debugPanelService).RootObject; | |||
|  |             root.Canvas.gameObject.RemoveComponentIfExists<SRRetinaScaler>(); | |||
|  |             root.Canvas.gameObject.RemoveComponentIfExists<CanvasScaler>(); | |||
|  |             root.Canvas.renderMode = RenderMode.WorldSpace; | |||
|  | 
 | |||
|  |             var rectTransform = root.Canvas.GetComponent<RectTransform>(); | |||
|  |             rectTransform.sizeDelta = new Vector2(1024, 768); | |||
|  |             rectTransform.position = Vector3.zero; | |||
|  | 
 | |||
|  |             return _worldSpaceTransform = rectTransform; | |||
|  |         } | |||
|  |     } | |||
|  | } |