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