123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749 |
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Text;
- using UnityEngine;
- using UnityEngine.UI;
- using UnityEngine.EventSystems;
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- using UnityEngine.InputSystem;
- #endif
- #if UNITY_EDITOR && UNITY_2021_1_OR_NEWER
- using Screen = UnityEngine.Device.Screen;
- #endif
- namespace IngameDebugConsole
- {
- public enum DebugLogFilter
- {
- None = 0,
- Info = 1,
- Warning = 2,
- Error = 4,
- All = 7
- }
- public class DebugLogManager : MonoBehaviour
- {
- public static DebugLogManager Instance { get; private set; }
- #pragma warning disable 0649
- [Header( "Properties" )]
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, console window will persist between scenes (i.e. not be destroyed when scene changes)" )]
- private bool singleton = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "Minimum height of the console window" )]
- private float minimumHeight = 200f;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, console window can be resized horizontally, as well" )]
- private bool enableHorizontalResizing = false;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, console window's resize button will be located at bottom-right corner. Otherwise, it will be located at bottom-left corner" )]
- private bool resizeFromRight = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "Minimum width of the console window" )]
- private float minimumWidth = 240f;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If disabled, no popup will be shown when the console window is hidden" )]
- private bool enablePopup = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, console will be initialized as a popup" )]
- private bool startInPopupMode = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, console window will initially be invisible" )]
- private bool startMinimized = false;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, pressing the Toggle Key will show/hide (i.e. toggle) the console window at runtime" )]
- private bool toggleWithKey = false;
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- [SerializeField]
- [HideInInspector]
- public InputAction toggleBinding = new InputAction( "Toggle Binding", type: InputActionType.Button, binding: "<Keyboard>/backquote", expectedControlType: "Button" );
- #else
- [SerializeField]
- [HideInInspector]
- private KeyCode toggleKey = KeyCode.BackQuote;
- #endif
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, the console window will have a searchbar" )]
- private bool enableSearchbar = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "Width of the canvas determines whether the searchbar will be located inside the menu bar or underneath the menu bar. This way, the menu bar doesn't get too crowded on narrow screens. This value determines the minimum width of the canvas for the searchbar to appear inside the menu bar" )]
- private float topSearchbarMinWidth = 360f;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, the console window will continue receiving logs in the background even if its GameObject is inactive. But the console window's GameObject needs to be activated at least once because its Awake function must be triggered for this to work" )]
- private bool receiveLogsWhileInactive = false;
- [SerializeField]
- [HideInInspector]
- private bool receiveInfoLogs = true, receiveWarningLogs = true, receiveErrorLogs = true, receiveExceptionLogs = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, the arrival times of logs will be recorded and displayed when a log is expanded" )]
- private bool captureLogTimestamps = false;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, timestamps will be displayed for logs even if they aren't expanded" )]
- internal bool alwaysDisplayTimestamps = false;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "While the console window is hidden, incoming logs will be queued but not immediately processed until the console window is opened (to avoid wasting CPU resources). When the log queue exceeds this limit, the first logs in the queue will be processed to enforce this limit. Processed logs won't increase RAM usage if they've been seen before (i.e. collapsible logs) but this is not the case for queued logs, so if a log is spammed every frame, it will fill the whole queue in an instant. Which is why there is a queue limit" )]
- private int queuedLogLimit = 256;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, the command input field at the bottom of the console window will automatically be cleared after entering a command" )]
- private bool clearCommandAfterExecution = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "Console keeps track of the previously entered commands. This value determines the capacity of the command history (you can scroll through the history via up and down arrow keys while the command input field is focused)" )]
- private int commandHistorySize = 15;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, while typing a command, all of the matching commands' signatures will be displayed in a popup" )]
- private bool showCommandSuggestions = true;
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, on Android platform, logcat entries of the application will also be logged to the console with the prefix \"LOGCAT: \". This may come in handy especially if you want to access the native logs of your Android plugins (like Admob)" )]
- private bool receiveLogcatLogsInAndroid = false;
- #pragma warning disable 0414
- #if UNITY_2018_3_OR_NEWER // On older Unity versions, disabling CS0169 is problematic: "Cannot restore warning 'CS0169' because it was disabled globally"
- #pragma warning disable 0169
- #endif
- [SerializeField]
- [HideInInspector]
- [Tooltip( "Native logs will be filtered using these arguments. If left blank, all native logs of the application will be logged to the console. But if you want to e.g. see Admob's logs only, you can enter \"-s Ads\" (without quotes) here" )]
- private string logcatArguments;
- #if UNITY_2018_3_OR_NEWER
- #pragma warning restore 0169
- #endif
- #pragma warning restore 0414
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, on Android and iOS devices with notch screens, the console window will be repositioned so that the cutout(s) don't obscure it" )]
- private bool avoidScreenCutout = true;
- [SerializeField]
- [Tooltip( "If a log is longer than this limit, it will be truncated. This helps avoid reaching Unity's 65000 vertex limit for UI canvases" )]
- private int maxLogLength = 10000;
- #if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL
- [SerializeField]
- [HideInInspector]
- [Tooltip( "If enabled, on standalone platforms, command input field will automatically be focused (start receiving keyboard input) after opening the console window" )]
- private bool autoFocusOnCommandInputField = true;
- #endif
- [Header( "Visuals" )]
- [SerializeField]
- private DebugLogItem logItemPrefab;
- [SerializeField]
- private Text commandSuggestionPrefab;
-
- [SerializeField]
- private Sprite infoLog;
- [SerializeField]
- private Sprite warningLog;
- [SerializeField]
- private Sprite errorLog;
-
- [SerializeField]
- private Sprite resizeIconAllDirections;
- [SerializeField]
- private Sprite resizeIconVerticalOnly;
- private Dictionary<LogType, Sprite> logSpriteRepresentations;
- [SerializeField]
- private Color collapseButtonNormalColor;
- [SerializeField]
- private Color collapseButtonSelectedColor;
- [SerializeField]
- private Color filterButtonsNormalColor;
- [SerializeField]
- private Color filterButtonsSelectedColor;
- [SerializeField]
- private string commandSuggestionHighlightStart = "<color=orange>";
- [SerializeField]
- private string commandSuggestionHighlightEnd = "</color>";
- [Header( "Internal References" )]
- [SerializeField]
- private RectTransform logWindowTR;
- internal RectTransform canvasTR;
- [SerializeField]
- private RectTransform logItemsContainer;
- [SerializeField]
- private RectTransform commandSuggestionsContainer;
- [SerializeField]
- private InputField commandInputField;
- [SerializeField]
- private Button hideButton;
- [SerializeField]
- private Button clearButton;
- [SerializeField]
- private Image collapseButton;
- [SerializeField]
- private Image filterInfoButton;
- [SerializeField]
- private Image filterWarningButton;
- [SerializeField]
- private Image filterErrorButton;
- [SerializeField]
- private Text infoEntryCountText;
- [SerializeField]
- private Text warningEntryCountText;
- [SerializeField]
- private Text errorEntryCountText;
- [SerializeField]
- private RectTransform searchbar;
- [SerializeField]
- private RectTransform searchbarSlotTop;
- [SerializeField]
- private RectTransform searchbarSlotBottom;
- [SerializeField]
- private Image resizeButton;
- [SerializeField]
- private GameObject snapToBottomButton;
-
- [SerializeField]
- private CanvasGroup logWindowCanvasGroup;
- [SerializeField]
- private DebugLogPopup popupManager;
- [SerializeField]
- private ScrollRect logItemsScrollRect;
- private RectTransform logItemsScrollRectTR;
- private Vector2 logItemsScrollRectOriginalSize;
-
- [SerializeField]
- private DebugLogRecycledListView recycledListView;
- #pragma warning restore 0649
- private bool isLogWindowVisible = true;
- public bool IsLogWindowVisible { get { return isLogWindowVisible; } }
- public bool PopupEnabled
- {
- get { return popupManager.gameObject.activeSelf; }
- set { popupManager.gameObject.SetActive( value ); }
- }
- private bool screenDimensionsChanged = true;
- private float logWindowPreviousWidth;
-
- private int infoEntryCount = 0, warningEntryCount = 0, errorEntryCount = 0;
- private bool entryCountTextsDirty;
-
- private int newInfoEntryCount = 0, newWarningEntryCount = 0, newErrorEntryCount = 0;
-
- private bool isCollapseOn = false;
- private DebugLogFilter logFilter = DebugLogFilter.All;
-
- private string searchTerm;
- private bool isInSearchMode;
-
-
- private bool snapToBottom = true;
-
- private List<DebugLogEntry> collapsedLogEntries;
- private List<DebugLogEntryTimestamp> collapsedLogEntriesTimestamps;
-
- private Dictionary<DebugLogEntry, int> collapsedLogEntriesMap;
-
-
- private DebugLogIndexList<int> uncollapsedLogEntriesIndices;
- private DebugLogIndexList<DebugLogEntryTimestamp> uncollapsedLogEntriesTimestamps;
-
- private DebugLogIndexList<int> indicesOfListEntriesToShow;
- private DebugLogIndexList<DebugLogEntryTimestamp> timestampsOfListEntriesToShow;
-
- private int indexOfLogEntryToSelectAndFocus = -1;
-
- private bool shouldUpdateRecycledListView = false;
-
- private DynamicCircularBuffer<QueuedDebugLogEntry> queuedLogEntries;
- private DynamicCircularBuffer<DebugLogEntryTimestamp> queuedLogEntriesTimestamps;
- private object logEntriesLock;
- private int pendingLogToAutoExpand;
-
- private List<Text> commandSuggestionInstances;
- private int visibleCommandSuggestionInstances = 0;
- private List<ConsoleMethodInfo> matchingCommandSuggestions;
- private List<int> commandCaretIndexIncrements;
- private string commandInputFieldPrevCommand;
- private string commandInputFieldPrevCommandName;
- private int commandInputFieldPrevParamCount = -1;
- private int commandInputFieldPrevCaretPos = -1;
- private int commandInputFieldPrevCaretArgumentIndex = -1;
-
- private string commandInputFieldAutoCompleteBase;
- private bool commandInputFieldAutoCompletedNow;
-
- private List<DebugLogEntry> pooledLogEntries;
- private List<DebugLogItem> pooledLogItems;
-
- private CircularBuffer<string> commandHistory;
- private int commandHistoryIndex = -1;
- private string unfinishedCommand;
-
- internal StringBuilder sharedStringBuilder;
-
- private System.TimeSpan localTimeUtcOffset;
-
- #if !IDG_OMIT_ELAPSED_TIME
- private float lastElapsedSeconds;
- #endif
- #if !IDG_OMIT_FRAMECOUNT
- private int lastFrameCount;
- #endif
- private DebugLogEntryTimestamp dummyLogEntryTimestamp;
-
- private PointerEventData nullPointerEventData;
-
- public System.Action OnLogWindowShown, OnLogWindowHidden;
- #if UNITY_EDITOR
- private bool isQuittingApplication;
- #endif
- #if !UNITY_EDITOR && UNITY_ANDROID
- private DebugLogLogcatListener logcatListener;
- #endif
- private void Awake()
- {
-
- if( !Instance )
- {
- Instance = this;
-
- if( singleton )
- DontDestroyOnLoad( gameObject );
- }
- else if( Instance != this )
- {
- Destroy( gameObject );
- return;
- }
- pooledLogEntries = new List<DebugLogEntry>( 16 );
- pooledLogItems = new List<DebugLogItem>( 16 );
- commandSuggestionInstances = new List<Text>( 8 );
- matchingCommandSuggestions = new List<ConsoleMethodInfo>( 8 );
- commandCaretIndexIncrements = new List<int>( 8 );
- queuedLogEntries = new DynamicCircularBuffer<QueuedDebugLogEntry>( Mathf.Clamp( queuedLogLimit, 16, 4096 ) );
- commandHistory = new CircularBuffer<string>( commandHistorySize );
- logEntriesLock = new object();
- sharedStringBuilder = new StringBuilder( 1024 );
- canvasTR = (RectTransform) transform;
- logItemsScrollRectTR = (RectTransform) logItemsScrollRect.transform;
- logItemsScrollRectOriginalSize = logItemsScrollRectTR.sizeDelta;
-
- logSpriteRepresentations = new Dictionary<LogType, Sprite>()
- {
- { LogType.Log, infoLog },
- { LogType.Warning, warningLog },
- { LogType.Error, errorLog },
- { LogType.Exception, errorLog },
- { LogType.Assert, errorLog }
- };
-
- filterInfoButton.color = filterButtonsSelectedColor;
- filterWarningButton.color = filterButtonsSelectedColor;
- filterErrorButton.color = filterButtonsSelectedColor;
- resizeButton.sprite = enableHorizontalResizing ? resizeIconAllDirections : resizeIconVerticalOnly;
- collapsedLogEntries = new List<DebugLogEntry>( 128 );
- collapsedLogEntriesMap = new Dictionary<DebugLogEntry, int>( 128 );
- uncollapsedLogEntriesIndices = new DebugLogIndexList<int>();
- indicesOfListEntriesToShow = new DebugLogIndexList<int>();
- if( captureLogTimestamps )
- {
- collapsedLogEntriesTimestamps = new List<DebugLogEntryTimestamp>( 128 );
- uncollapsedLogEntriesTimestamps = new DebugLogIndexList<DebugLogEntryTimestamp>();
- timestampsOfListEntriesToShow = new DebugLogIndexList<DebugLogEntryTimestamp>();
- queuedLogEntriesTimestamps = new DynamicCircularBuffer<DebugLogEntryTimestamp>( queuedLogEntries.Capacity );
- }
- recycledListView.Initialize( this, collapsedLogEntries, indicesOfListEntriesToShow, timestampsOfListEntriesToShow, logItemPrefab.Transform.sizeDelta.y );
- recycledListView.UpdateItemsInTheList( true );
- if( minimumWidth < 100f )
- minimumWidth = 100f;
- if( minimumHeight < 200f )
- minimumHeight = 200f;
- if( !resizeFromRight )
- {
- RectTransform resizeButtonTR = (RectTransform) resizeButton.GetComponentInParent<DebugLogResizeListener>().transform;
- resizeButtonTR.anchorMin = new Vector2( 0f, resizeButtonTR.anchorMin.y );
- resizeButtonTR.anchorMax = new Vector2( 0f, resizeButtonTR.anchorMax.y );
- resizeButtonTR.pivot = new Vector2( 0f, resizeButtonTR.pivot.y );
- ( (RectTransform) commandInputField.transform ).anchoredPosition += new Vector2( resizeButtonTR.sizeDelta.x, 0f );
- }
- if( enableSearchbar )
- searchbar.GetComponent<InputField>().onValueChanged.AddListener( SearchTermChanged );
- else
- {
- searchbar = null;
- searchbarSlotTop.gameObject.SetActive( false );
- searchbarSlotBottom.gameObject.SetActive( false );
- }
- filterInfoButton.gameObject.SetActive( receiveInfoLogs );
- filterWarningButton.gameObject.SetActive( receiveWarningLogs );
- filterErrorButton.gameObject.SetActive( receiveErrorLogs || receiveExceptionLogs );
- if( commandSuggestionsContainer.gameObject.activeSelf )
- commandSuggestionsContainer.gameObject.SetActive( false );
-
- commandInputField.onValidateInput += OnValidateCommand;
- commandInputField.onValueChanged.AddListener( OnEditCommand );
- commandInputField.onEndEdit.AddListener( OnEndEditCommand );
- hideButton.onClick.AddListener( HideLogWindow );
- clearButton.onClick.AddListener( ClearLogs );
- collapseButton.GetComponent<Button>().onClick.AddListener( CollapseButtonPressed );
- filterInfoButton.GetComponent<Button>().onClick.AddListener( FilterLogButtonPressed );
- filterWarningButton.GetComponent<Button>().onClick.AddListener( FilterWarningButtonPressed );
- filterErrorButton.GetComponent<Button>().onClick.AddListener( FilterErrorButtonPressed );
- snapToBottomButton.GetComponent<Button>().onClick.AddListener( () => SetSnapToBottom( true ) );
- localTimeUtcOffset = System.DateTime.Now - System.DateTime.UtcNow;
- dummyLogEntryTimestamp = new DebugLogEntryTimestamp();
- nullPointerEventData = new PointerEventData( null );
- if( receiveLogsWhileInactive )
- {
- Application.logMessageReceivedThreaded -= ReceivedLog;
- Application.logMessageReceivedThreaded += ReceivedLog;
- }
- #if UNITY_EDITOR && UNITY_2018_1_OR_NEWER
-
-
- Application.quitting -= OnApplicationQuitting;
- Application.quitting += OnApplicationQuitting;
- #endif
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- toggleBinding.performed += ( context ) =>
- {
- if( toggleWithKey )
- {
- if( isLogWindowVisible )
- HideLogWindow();
- else
- ShowLogWindow();
- }
- };
-
- logItemsScrollRect.scrollSensitivity *= 0.25f;
- #endif
- }
- private void OnEnable()
- {
- if( Instance != this )
- return;
- if( !receiveLogsWhileInactive )
- {
- Application.logMessageReceivedThreaded -= ReceivedLog;
- Application.logMessageReceivedThreaded += ReceivedLog;
- }
- if( receiveLogcatLogsInAndroid )
- {
- #if !UNITY_EDITOR && UNITY_ANDROID
- if( logcatListener == null )
- logcatListener = new DebugLogLogcatListener();
- logcatListener.Start( logcatArguments );
- #endif
- }
- DebugLogConsole.AddCommand( "logs.save", "Saves logs to persistentDataPath", SaveLogsToFile );
- DebugLogConsole.AddCommand<string>( "logs.save", "Saves logs to the specified file", SaveLogsToFile );
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- if( toggleWithKey )
- toggleBinding.Enable();
- #endif
-
-
-
-
-
- }
- private void OnDisable()
- {
- if( Instance != this )
- return;
- if( !receiveLogsWhileInactive )
- Application.logMessageReceivedThreaded -= ReceivedLog;
- #if !UNITY_EDITOR && UNITY_ANDROID
- if( logcatListener != null )
- logcatListener.Stop();
- #endif
- DebugLogConsole.RemoveCommand( "logs.save" );
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- if( toggleBinding.enabled )
- toggleBinding.Disable();
- #endif
- }
- private void Start()
- {
- if( ( enablePopup && startInPopupMode ) || ( !enablePopup && startMinimized ) )
- HideLogWindow();
- else
- ShowLogWindow();
- PopupEnabled = enablePopup;
- }
- private void OnDestroy()
- {
- if( receiveLogsWhileInactive )
- Application.logMessageReceivedThreaded -= ReceivedLog;
- #if UNITY_EDITOR && UNITY_2018_1_OR_NEWER
- Application.quitting -= OnApplicationQuitting;
- #endif
- }
- #if UNITY_EDITOR
- private void OnValidate()
- {
- queuedLogLimit = Mathf.Max( 0, queuedLogLimit );
- if( UnityEditor.EditorApplication.isPlaying )
- {
- resizeButton.sprite = enableHorizontalResizing ? resizeIconAllDirections : resizeIconVerticalOnly;
- filterInfoButton.gameObject.SetActive( receiveInfoLogs );
- filterWarningButton.gameObject.SetActive( receiveWarningLogs );
- filterErrorButton.gameObject.SetActive( receiveErrorLogs || receiveExceptionLogs );
- }
- }
- #if UNITY_2018_1_OR_NEWER
- private void OnApplicationQuitting()
- #else
- private void OnApplicationQuit()
- #endif
- {
- isQuittingApplication = true;
- }
- #endif
-
- private void OnRectTransformDimensionsChange()
- {
- screenDimensionsChanged = true;
- }
- private void Update()
- {
- #if !IDG_OMIT_ELAPSED_TIME
- lastElapsedSeconds = Time.realtimeSinceStartup;
- #endif
- #if !IDG_OMIT_FRAMECOUNT
- lastFrameCount = Time.frameCount;
- #endif
- #if !UNITY_EDITOR && UNITY_ANDROID
- if( logcatListener != null )
- {
- string log;
- while( ( log = logcatListener.GetLog() ) != null )
- ReceivedLog( "LOGCAT: " + log, string.Empty, LogType.Log );
- }
- #endif
- #if !ENABLE_INPUT_SYSTEM || ENABLE_LEGACY_INPUT_MANAGER
-
-
-
-
- if( toggleWithKey )
- {
- if( Input.GetKeyDown( toggleKey ) )
- {
- if( isLogWindowVisible )
- HideLogWindow();
- else
- ShowLogWindow();
- }
- }
- #endif
- }
- private void LateUpdate()
- {
- #if UNITY_EDITOR
- if( isQuittingApplication )
- return;
- #endif
- int numberOfLogsToProcess = isLogWindowVisible ? queuedLogEntries.Count : ( queuedLogEntries.Count - queuedLogLimit );
- ProcessQueuedLogs( numberOfLogsToProcess );
-
- if( !isLogWindowVisible && !PopupEnabled )
- return;
- int newInfoEntryCount, newWarningEntryCount, newErrorEntryCount;
- lock( logEntriesLock )
- {
- newInfoEntryCount = this.newInfoEntryCount;
- newWarningEntryCount = this.newWarningEntryCount;
- newErrorEntryCount = this.newErrorEntryCount;
- this.newInfoEntryCount = 0;
- this.newWarningEntryCount = 0;
- this.newErrorEntryCount = 0;
- }
-
- if( newInfoEntryCount > 0 || newWarningEntryCount > 0 || newErrorEntryCount > 0 )
- {
- if( newInfoEntryCount > 0 )
- {
- infoEntryCount += newInfoEntryCount;
- if( isLogWindowVisible )
- infoEntryCountText.text = infoEntryCount.ToString();
- }
- if( newWarningEntryCount > 0 )
- {
- warningEntryCount += newWarningEntryCount;
- if( isLogWindowVisible )
- warningEntryCountText.text = warningEntryCount.ToString();
- }
- if( newErrorEntryCount > 0 )
- {
- errorEntryCount += newErrorEntryCount;
- if( isLogWindowVisible )
- errorEntryCountText.text = errorEntryCount.ToString();
- }
-
- if( !isLogWindowVisible )
- {
- entryCountTextsDirty = true;
- popupManager.NewLogsArrived( newInfoEntryCount, newWarningEntryCount, newErrorEntryCount );
- }
- }
- if( isLogWindowVisible )
- {
-
- if( shouldUpdateRecycledListView )
- {
- recycledListView.OnLogEntriesUpdated( false );
- shouldUpdateRecycledListView = false;
- }
-
- if( indexOfLogEntryToSelectAndFocus >= 0 )
- {
- if( indexOfLogEntryToSelectAndFocus < indicesOfListEntriesToShow.Count )
- recycledListView.SelectAndFocusOnLogItemAtIndex( indexOfLogEntryToSelectAndFocus );
- indexOfLogEntryToSelectAndFocus = -1;
- }
- float logWindowWidth = logWindowTR.rect.width;
- if( !Mathf.Approximately( logWindowWidth, logWindowPreviousWidth ) )
- {
- logWindowPreviousWidth = logWindowWidth;
- if( searchbar )
- {
- if( logWindowWidth >= topSearchbarMinWidth )
- {
- if( searchbar.parent == searchbarSlotBottom )
- {
- searchbarSlotTop.gameObject.SetActive( true );
- searchbar.SetParent( searchbarSlotTop, false );
- searchbarSlotBottom.gameObject.SetActive( false );
- logItemsScrollRectTR.anchoredPosition = Vector2.zero;
- logItemsScrollRectTR.sizeDelta = logItemsScrollRectOriginalSize;
- }
- }
- else
- {
- if( searchbar.parent == searchbarSlotTop )
- {
- searchbarSlotBottom.gameObject.SetActive( true );
- searchbar.SetParent( searchbarSlotBottom, false );
- searchbarSlotTop.gameObject.SetActive( false );
- float searchbarHeight = searchbarSlotBottom.sizeDelta.y;
- logItemsScrollRectTR.anchoredPosition = new Vector2( 0f, searchbarHeight * -0.5f );
- logItemsScrollRectTR.sizeDelta = logItemsScrollRectOriginalSize - new Vector2( 0f, searchbarHeight );
- }
- }
- }
- recycledListView.OnViewportWidthChanged();
- }
-
- if( snapToBottom )
- {
- logItemsScrollRect.verticalNormalizedPosition = 0f;
- if( snapToBottomButton.activeSelf )
- snapToBottomButton.SetActive( false );
- }
- else
- {
- float scrollPos = logItemsScrollRect.verticalNormalizedPosition;
- if( snapToBottomButton.activeSelf != ( scrollPos > 1E-6f && scrollPos < 0.9999f ) )
- snapToBottomButton.SetActive( !snapToBottomButton.activeSelf );
- }
- if( showCommandSuggestions && commandInputField.isFocused && commandInputField.caretPosition != commandInputFieldPrevCaretPos )
- RefreshCommandSuggestions( commandInputField.text );
- if( commandInputField.isFocused && commandHistory.Count > 0 )
- {
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- if( Keyboard.current != null )
- #endif
- {
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- if( Keyboard.current[Key.UpArrow].wasPressedThisFrame )
- #else
- if( Input.GetKeyDown( KeyCode.UpArrow ) )
- #endif
- {
- if( commandHistoryIndex == -1 )
- {
- commandHistoryIndex = commandHistory.Count - 1;
- unfinishedCommand = commandInputField.text;
- }
- else if( --commandHistoryIndex < 0 )
- commandHistoryIndex = 0;
- commandInputField.text = commandHistory[commandHistoryIndex];
- commandInputField.caretPosition = commandInputField.text.Length;
- }
- #if ENABLE_INPUT_SYSTEM && !ENABLE_LEGACY_INPUT_MANAGER
- else if( Keyboard.current[Key.DownArrow].wasPressedThisFrame && commandHistoryIndex != -1 )
- #else
- else if( Input.GetKeyDown( KeyCode.DownArrow ) && commandHistoryIndex != -1 )
- #endif
- {
- if( ++commandHistoryIndex < commandHistory.Count )
- commandInputField.text = commandHistory[commandHistoryIndex];
- else
- {
- commandHistoryIndex = -1;
- commandInputField.text = unfinishedCommand ?? string.Empty;
- }
- }
- }
- }
- }
- if( screenDimensionsChanged )
- {
-
- if( isLogWindowVisible )
- recycledListView.OnViewportHeightChanged();
- else
- popupManager.UpdatePosition( true );
- #if UNITY_EDITOR || UNITY_ANDROID || UNITY_IOS
- CheckScreenCutout();
- #endif
- screenDimensionsChanged = false;
- }
- }
- public void ShowLogWindow()
- {
-
- logWindowCanvasGroup.blocksRaycasts = true;
- logWindowCanvasGroup.alpha = 1f;
- popupManager.Hide();
-
-
- recycledListView.OnLogEntriesUpdated( true );
- #if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL
-
- if( autoFocusOnCommandInputField )
- StartCoroutine( ActivateCommandInputFieldCoroutine() );
- #endif
- if( entryCountTextsDirty )
- {
- infoEntryCountText.text = infoEntryCount.ToString();
- warningEntryCountText.text = warningEntryCount.ToString();
- errorEntryCountText.text = errorEntryCount.ToString();
- entryCountTextsDirty = false;
- }
- isLogWindowVisible = true;
- if( OnLogWindowShown != null )
- OnLogWindowShown();
- }
- public void HideLogWindow()
- {
-
- logWindowCanvasGroup.blocksRaycasts = false;
- logWindowCanvasGroup.alpha = 0f;
- if( commandInputField.isFocused )
- commandInputField.DeactivateInputField();
- popupManager.Show();
- isLogWindowVisible = false;
- if( OnLogWindowHidden != null )
- OnLogWindowHidden();
- }
-
- private char OnValidateCommand( string text, int charIndex, char addedChar )
- {
- if( addedChar == '\t' )
- {
- if( !string.IsNullOrEmpty( text ) )
- {
- if( string.IsNullOrEmpty( commandInputFieldAutoCompleteBase ) )
- commandInputFieldAutoCompleteBase = text;
- string autoCompletedCommand = DebugLogConsole.GetAutoCompleteCommand( commandInputFieldAutoCompleteBase, text );
- if( !string.IsNullOrEmpty( autoCompletedCommand ) && autoCompletedCommand != text )
- {
- commandInputFieldAutoCompletedNow = true;
- commandInputField.text = autoCompletedCommand;
- }
- }
- return '\0';
- }
- else if( addedChar == '\n' )
- {
-
- if( clearCommandAfterExecution )
- commandInputField.text = string.Empty;
- if( text.Length > 0 )
- {
- if( commandHistory.Count == 0 || commandHistory[commandHistory.Count - 1] != text )
- commandHistory.Add( text );
- commandHistoryIndex = -1;
- unfinishedCommand = null;
-
- DebugLogConsole.ExecuteCommand( text );
-
- SetSnapToBottom( true );
- }
- return '\0';
- }
- return addedChar;
- }
-
- public void ReceivedLog( string logString, string stackTrace, LogType logType )
- {
- #if UNITY_EDITOR
- if( isQuittingApplication )
- return;
- #endif
- switch( logType )
- {
- case LogType.Log: if( !receiveInfoLogs ) return; break;
- case LogType.Warning: if( !receiveWarningLogs ) return; break;
- case LogType.Error: if( !receiveErrorLogs ) return; break;
- case LogType.Assert:
- case LogType.Exception: if( !receiveExceptionLogs ) return; break;
- }
-
- int logLength = logString.Length;
- if( stackTrace == null )
- {
- if( logLength > maxLogLength )
- logString = logString.Substring( 0, maxLogLength - 11 ) + "<truncated>";
- }
- else
- {
- logLength += stackTrace.Length;
- if( logLength > maxLogLength )
- {
-
- int halfMaxLogLength = maxLogLength / 2;
- if( logString.Length >= halfMaxLogLength )
- {
- if( stackTrace.Length >= halfMaxLogLength )
- {
-
- logString = logString.Substring( 0, halfMaxLogLength - 11 ) + "<truncated>";
-
- stackTrace = stackTrace.Substring( 0, halfMaxLogLength - 12 ) + "<truncated>\n";
- }
- else
- {
-
- logString = logString.Substring( 0, maxLogLength - stackTrace.Length - 11 ) + "<truncated>";
- }
- }
- else
- {
-
- stackTrace = stackTrace.Substring( 0, maxLogLength - logString.Length - 12 ) + "<truncated>\n";
- }
- }
- }
- QueuedDebugLogEntry queuedLogEntry = new QueuedDebugLogEntry( logString, stackTrace, logType );
- DebugLogEntryTimestamp queuedLogEntryTimestamp;
- if( queuedLogEntriesTimestamps != null )
- {
-
- System.DateTime dateTime = System.DateTime.UtcNow + localTimeUtcOffset;
- #if !IDG_OMIT_ELAPSED_TIME && !IDG_OMIT_FRAMECOUNT
- queuedLogEntryTimestamp = new DebugLogEntryTimestamp( dateTime, lastElapsedSeconds, lastFrameCount );
- #elif !IDG_OMIT_ELAPSED_TIME
- queuedLogEntryTimestamp = new DebugLogEntryTimestamp( dateTime, lastElapsedSeconds );
- #elif !IDG_OMIT_FRAMECOUNT
- queuedLogEntryTimestamp = new DebugLogEntryTimestamp( dateTime, lastFrameCount );
- #else
- queuedLogEntryTimestamp = new DebugLogEntryTimestamp( dateTime );
- #endif
- }
- else
- queuedLogEntryTimestamp = dummyLogEntryTimestamp;
- lock( logEntriesLock )
- {
- queuedLogEntries.Add( queuedLogEntry );
- if( queuedLogEntriesTimestamps != null )
- queuedLogEntriesTimestamps.Add( queuedLogEntryTimestamp );
- if( logType == LogType.Log )
- newInfoEntryCount++;
- else if( logType == LogType.Warning )
- newWarningEntryCount++;
- else
- newErrorEntryCount++;
- }
- }
-
- private void ProcessQueuedLogs( int numberOfLogsToProcess )
- {
- for( int i = 0; i < numberOfLogsToProcess; i++ )
- {
- QueuedDebugLogEntry logEntry;
- DebugLogEntryTimestamp timestamp;
- lock( logEntriesLock )
- {
- logEntry = queuedLogEntries.RemoveFirst();
- timestamp = queuedLogEntriesTimestamps != null ? queuedLogEntriesTimestamps.RemoveFirst() : dummyLogEntryTimestamp;
- }
- ProcessLog( logEntry, timestamp );
- }
- }
-
- private void ProcessLog( QueuedDebugLogEntry queuedLogEntry, DebugLogEntryTimestamp timestamp )
- {
- LogType logType = queuedLogEntry.logType;
- DebugLogEntry logEntry;
- if( pooledLogEntries.Count > 0 )
- {
- logEntry = pooledLogEntries[pooledLogEntries.Count - 1];
- pooledLogEntries.RemoveAt( pooledLogEntries.Count - 1 );
- }
- else
- logEntry = new DebugLogEntry();
- logEntry.Initialize( queuedLogEntry.logString, queuedLogEntry.stackTrace );
-
- int logEntryIndex;
- bool isEntryInCollapsedEntryList = collapsedLogEntriesMap.TryGetValue( logEntry, out logEntryIndex );
- if( !isEntryInCollapsedEntryList )
- {
-
-
- logEntry.logTypeSpriteRepresentation = logSpriteRepresentations[logType];
- logEntryIndex = collapsedLogEntries.Count;
- collapsedLogEntries.Add( logEntry );
- collapsedLogEntriesMap[logEntry] = logEntryIndex;
- if( collapsedLogEntriesTimestamps != null )
- collapsedLogEntriesTimestamps.Add( timestamp );
- }
- else
- {
-
-
- pooledLogEntries.Add( logEntry );
- logEntry = collapsedLogEntries[logEntryIndex];
- logEntry.count++;
- if( collapsedLogEntriesTimestamps != null )
- collapsedLogEntriesTimestamps[logEntryIndex] = timestamp;
- }
-
-
- uncollapsedLogEntriesIndices.Add( logEntryIndex );
-
- if( uncollapsedLogEntriesTimestamps != null )
- uncollapsedLogEntriesTimestamps.Add( timestamp );
-
-
- int logEntryIndexInEntriesToShow = -1;
- Sprite logTypeSpriteRepresentation = logEntry.logTypeSpriteRepresentation;
- if( isCollapseOn && isEntryInCollapsedEntryList )
- {
- if( isLogWindowVisible || timestampsOfListEntriesToShow != null )
- {
- if( !isInSearchMode && logFilter == DebugLogFilter.All )
- logEntryIndexInEntriesToShow = logEntryIndex;
- else
- logEntryIndexInEntriesToShow = indicesOfListEntriesToShow.IndexOf( logEntryIndex );
- if( logEntryIndexInEntriesToShow >= 0 )
- {
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow[logEntryIndexInEntriesToShow] = timestamp;
- if( isLogWindowVisible )
- recycledListView.OnCollapsedLogEntryAtIndexUpdated( logEntryIndexInEntriesToShow );
- }
- }
- }
- else if( ( !isInSearchMode || queuedLogEntry.MatchesSearchTerm( searchTerm ) ) && ( logFilter == DebugLogFilter.All ||
- ( logTypeSpriteRepresentation == infoLog && ( ( logFilter & DebugLogFilter.Info ) == DebugLogFilter.Info ) ) ||
- ( logTypeSpriteRepresentation == warningLog && ( ( logFilter & DebugLogFilter.Warning ) == DebugLogFilter.Warning ) ) ||
- ( logTypeSpriteRepresentation == errorLog && ( ( logFilter & DebugLogFilter.Error ) == DebugLogFilter.Error ) ) ) )
- {
- indicesOfListEntriesToShow.Add( logEntryIndex );
- logEntryIndexInEntriesToShow = indicesOfListEntriesToShow.Count - 1;
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Add( timestamp );
- shouldUpdateRecycledListView = true;
- }
-
- if( pendingLogToAutoExpand > 0 && --pendingLogToAutoExpand <= 0 && logEntryIndexInEntriesToShow >= 0 )
- indexOfLogEntryToSelectAndFocus = logEntryIndexInEntriesToShow;
- }
-
- public void SetSnapToBottom( bool snapToBottom )
- {
- this.snapToBottom = snapToBottom;
- }
-
- internal void ValidateScrollPosition()
- {
-
- if( logItemsScrollRect.verticalNormalizedPosition <= Mathf.Epsilon )
- logItemsScrollRect.verticalNormalizedPosition = 0.0001f;
- logItemsScrollRect.OnScroll( nullPointerEventData );
- }
-
- public void AdjustLatestPendingLog( bool autoExpand, bool stripStackTrace )
- {
- lock( logEntriesLock )
- {
- if( queuedLogEntries.Count == 0 )
- return;
- if( autoExpand )
- pendingLogToAutoExpand = queuedLogEntries.Count;
- if( stripStackTrace )
- {
- QueuedDebugLogEntry log = queuedLogEntries[queuedLogEntries.Count - 1];
- queuedLogEntries[queuedLogEntries.Count - 1] = new QueuedDebugLogEntry( log.logString, string.Empty, log.logType );
- }
- }
- }
-
- public void ClearLogs()
- {
- snapToBottom = true;
- infoEntryCount = 0;
- warningEntryCount = 0;
- errorEntryCount = 0;
- infoEntryCountText.text = "0";
- warningEntryCountText.text = "0";
- errorEntryCountText.text = "0";
- collapsedLogEntries.Clear();
- collapsedLogEntriesMap.Clear();
- uncollapsedLogEntriesIndices.Clear();
- indicesOfListEntriesToShow.Clear();
- if( collapsedLogEntriesTimestamps != null )
- {
- collapsedLogEntriesTimestamps.Clear();
- uncollapsedLogEntriesTimestamps.Clear();
- timestampsOfListEntriesToShow.Clear();
- }
- recycledListView.DeselectSelectedLogItem();
- recycledListView.OnLogEntriesUpdated( true );
- }
-
- private void CollapseButtonPressed()
- {
-
- isCollapseOn = !isCollapseOn;
- snapToBottom = true;
- collapseButton.color = isCollapseOn ? collapseButtonSelectedColor : collapseButtonNormalColor;
- recycledListView.SetCollapseMode( isCollapseOn );
-
- FilterLogs();
- }
-
- private void FilterLogButtonPressed()
- {
- logFilter = logFilter ^ DebugLogFilter.Info;
- if( ( logFilter & DebugLogFilter.Info ) == DebugLogFilter.Info )
- filterInfoButton.color = filterButtonsSelectedColor;
- else
- filterInfoButton.color = filterButtonsNormalColor;
- FilterLogs();
- }
-
- private void FilterWarningButtonPressed()
- {
- logFilter = logFilter ^ DebugLogFilter.Warning;
- if( ( logFilter & DebugLogFilter.Warning ) == DebugLogFilter.Warning )
- filterWarningButton.color = filterButtonsSelectedColor;
- else
- filterWarningButton.color = filterButtonsNormalColor;
- FilterLogs();
- }
-
- private void FilterErrorButtonPressed()
- {
- logFilter = logFilter ^ DebugLogFilter.Error;
- if( ( logFilter & DebugLogFilter.Error ) == DebugLogFilter.Error )
- filterErrorButton.color = filterButtonsSelectedColor;
- else
- filterErrorButton.color = filterButtonsNormalColor;
- FilterLogs();
- }
-
- private void SearchTermChanged( string searchTerm )
- {
- if( searchTerm != null )
- searchTerm = searchTerm.Trim();
- this.searchTerm = searchTerm;
- bool isInSearchMode = !string.IsNullOrEmpty( searchTerm );
- if( isInSearchMode || this.isInSearchMode )
- {
- this.isInSearchMode = isInSearchMode;
- FilterLogs();
- }
- }
-
- private void RefreshCommandSuggestions( string command )
- {
- if( !showCommandSuggestions )
- return;
- commandInputFieldPrevCaretPos = commandInputField.caretPosition;
-
- bool commandChanged = command != commandInputFieldPrevCommand;
- bool commandNameOrParametersChanged = false;
- if( commandChanged )
- {
- commandInputFieldPrevCommand = command;
- matchingCommandSuggestions.Clear();
- commandCaretIndexIncrements.Clear();
- string prevCommandName = commandInputFieldPrevCommandName;
- int numberOfParameters;
- DebugLogConsole.GetCommandSuggestions( command, matchingCommandSuggestions, commandCaretIndexIncrements, ref commandInputFieldPrevCommandName, out numberOfParameters );
- if( prevCommandName != commandInputFieldPrevCommandName || numberOfParameters != commandInputFieldPrevParamCount )
- {
- commandInputFieldPrevParamCount = numberOfParameters;
- commandNameOrParametersChanged = true;
- }
- }
- int caretArgumentIndex = 0;
- int caretPos = commandInputField.caretPosition;
- for( int i = 0; i < commandCaretIndexIncrements.Count && caretPos > commandCaretIndexIncrements[i]; i++ )
- caretArgumentIndex++;
- if( caretArgumentIndex != commandInputFieldPrevCaretArgumentIndex )
- commandInputFieldPrevCaretArgumentIndex = caretArgumentIndex;
- else if( !commandChanged || !commandNameOrParametersChanged )
- {
-
-
-
-
- return;
- }
- if( matchingCommandSuggestions.Count == 0 )
- OnEndEditCommand( command );
- else
- {
- if( !commandSuggestionsContainer.gameObject.activeSelf )
- commandSuggestionsContainer.gameObject.SetActive( true );
- int suggestionInstancesCount = commandSuggestionInstances.Count;
- int suggestionsCount = matchingCommandSuggestions.Count;
- for( int i = 0; i < suggestionsCount; i++ )
- {
- if( i >= visibleCommandSuggestionInstances )
- {
- if( i >= suggestionInstancesCount )
- commandSuggestionInstances.Add( (Text) Instantiate( commandSuggestionPrefab, commandSuggestionsContainer, false ) );
- else
- commandSuggestionInstances[i].gameObject.SetActive( true );
- visibleCommandSuggestionInstances++;
- }
- ConsoleMethodInfo suggestedCommand = matchingCommandSuggestions[i];
- sharedStringBuilder.Length = 0;
- if( caretArgumentIndex > 0 )
- sharedStringBuilder.Append( suggestedCommand.command );
- else
- sharedStringBuilder.Append( commandSuggestionHighlightStart ).Append( matchingCommandSuggestions[i].command ).Append( commandSuggestionHighlightEnd );
- if( suggestedCommand.parameters.Length > 0 )
- {
- sharedStringBuilder.Append( " " );
-
- int caretParameterIndex = caretArgumentIndex - 1;
- if( caretParameterIndex >= suggestedCommand.parameters.Length )
- caretParameterIndex = suggestedCommand.parameters.Length - 1;
- for( int j = 0; j < suggestedCommand.parameters.Length; j++ )
- {
- if( caretParameterIndex != j )
- sharedStringBuilder.Append( suggestedCommand.parameters[j] );
- else
- sharedStringBuilder.Append( commandSuggestionHighlightStart ).Append( suggestedCommand.parameters[j] ).Append( commandSuggestionHighlightEnd );
- }
- }
- commandSuggestionInstances[i].text = sharedStringBuilder.ToString();
- }
- for( int i = visibleCommandSuggestionInstances - 1; i >= suggestionsCount; i-- )
- commandSuggestionInstances[i].gameObject.SetActive( false );
- visibleCommandSuggestionInstances = suggestionsCount;
- }
- }
-
- private void OnEditCommand( string command )
- {
- RefreshCommandSuggestions( command );
- if( !commandInputFieldAutoCompletedNow )
- commandInputFieldAutoCompleteBase = null;
- else
- commandInputFieldAutoCompletedNow = false;
- }
-
- private void OnEndEditCommand( string command )
- {
- if( commandSuggestionsContainer.gameObject.activeSelf )
- commandSuggestionsContainer.gameObject.SetActive( false );
- }
-
-
-
- internal void Resize( PointerEventData eventData )
- {
- Vector2 localPoint;
- if( !RectTransformUtility.ScreenPointToLocalPointInRectangle( canvasTR, eventData.position, eventData.pressEventCamera, out localPoint ) )
- return;
-
-
-
- const float resizeButtonWidth = 64f;
- const float resizeButtonHeight = 36f;
- Vector2 canvasPivot = canvasTR.pivot;
- Vector2 canvasSize = canvasTR.rect.size;
- Vector2 anchorMin = logWindowTR.anchorMin;
-
- if( enableHorizontalResizing )
- {
- if( resizeFromRight )
- {
- localPoint.x += canvasPivot.x * canvasSize.x + resizeButtonWidth;
- if( localPoint.x < minimumWidth )
- localPoint.x = minimumWidth;
- Vector2 anchorMax = logWindowTR.anchorMax;
- anchorMax.x = Mathf.Clamp01( localPoint.x / canvasSize.x );
- logWindowTR.anchorMax = anchorMax;
- }
- else
- {
- localPoint.x += canvasPivot.x * canvasSize.x - resizeButtonWidth;
- if( localPoint.x > canvasSize.x - minimumWidth )
- localPoint.x = canvasSize.x - minimumWidth;
- anchorMin.x = Mathf.Clamp01( localPoint.x / canvasSize.x );
- }
- }
-
- float notchHeight = -logWindowTR.sizeDelta.y;
- localPoint.y += canvasPivot.y * canvasSize.y - resizeButtonHeight;
- if( localPoint.y > canvasSize.y - minimumHeight - notchHeight )
- localPoint.y = canvasSize.y - minimumHeight - notchHeight;
- anchorMin.y = Mathf.Clamp01( localPoint.y / canvasSize.y );
- logWindowTR.anchorMin = anchorMin;
-
- recycledListView.OnViewportHeightChanged();
- }
-
- private void FilterLogs()
- {
- indicesOfListEntriesToShow.Clear();
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Clear();
- if( logFilter != DebugLogFilter.None )
- {
- if( logFilter == DebugLogFilter.All )
- {
- if( isCollapseOn )
- {
- if( !isInSearchMode )
- {
-
-
-
- for( int i = 0, count = collapsedLogEntries.Count; i < count; i++ )
- {
- indicesOfListEntriesToShow.Add( i );
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Add( collapsedLogEntriesTimestamps[i] );
- }
- }
- else
- {
- for( int i = 0, count = collapsedLogEntries.Count; i < count; i++ )
- {
- if( collapsedLogEntries[i].MatchesSearchTerm( searchTerm ) )
- {
- indicesOfListEntriesToShow.Add( i );
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Add( collapsedLogEntriesTimestamps[i] );
- }
- }
- }
- }
- else
- {
- if( !isInSearchMode )
- {
- for( int i = 0, count = uncollapsedLogEntriesIndices.Count; i < count; i++ )
- {
- indicesOfListEntriesToShow.Add( uncollapsedLogEntriesIndices[i] );
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Add( uncollapsedLogEntriesTimestamps[i] );
- }
- }
- else
- {
- for( int i = 0, count = uncollapsedLogEntriesIndices.Count; i < count; i++ )
- {
- if( collapsedLogEntries[uncollapsedLogEntriesIndices[i]].MatchesSearchTerm( searchTerm ) )
- {
- indicesOfListEntriesToShow.Add( uncollapsedLogEntriesIndices[i] );
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Add( uncollapsedLogEntriesTimestamps[i] );
- }
- }
- }
- }
- }
- else
- {
-
- bool isInfoEnabled = ( logFilter & DebugLogFilter.Info ) == DebugLogFilter.Info;
- bool isWarningEnabled = ( logFilter & DebugLogFilter.Warning ) == DebugLogFilter.Warning;
- bool isErrorEnabled = ( logFilter & DebugLogFilter.Error ) == DebugLogFilter.Error;
- if( isCollapseOn )
- {
- for( int i = 0, count = collapsedLogEntries.Count; i < count; i++ )
- {
- DebugLogEntry logEntry = collapsedLogEntries[i];
- if( isInSearchMode && !logEntry.MatchesSearchTerm( searchTerm ) )
- continue;
- bool shouldShowLog = false;
- if( logEntry.logTypeSpriteRepresentation == infoLog )
- {
- if( isInfoEnabled )
- shouldShowLog = true;
- }
- else if( logEntry.logTypeSpriteRepresentation == warningLog )
- {
- if( isWarningEnabled )
- shouldShowLog = true;
- }
- else if( isErrorEnabled )
- shouldShowLog = true;
- if( shouldShowLog )
- {
- indicesOfListEntriesToShow.Add( i );
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Add( collapsedLogEntriesTimestamps[i] );
- }
- }
- }
- else
- {
- for( int i = 0, count = uncollapsedLogEntriesIndices.Count; i < count; i++ )
- {
- DebugLogEntry logEntry = collapsedLogEntries[uncollapsedLogEntriesIndices[i]];
- if( isInSearchMode && !logEntry.MatchesSearchTerm( searchTerm ) )
- continue;
- bool shouldShowLog = false;
- if( logEntry.logTypeSpriteRepresentation == infoLog )
- {
- if( isInfoEnabled )
- shouldShowLog = true;
- }
- else if( logEntry.logTypeSpriteRepresentation == warningLog )
- {
- if( isWarningEnabled )
- shouldShowLog = true;
- }
- else if( isErrorEnabled )
- shouldShowLog = true;
- if( shouldShowLog )
- {
- indicesOfListEntriesToShow.Add( uncollapsedLogEntriesIndices[i] );
- if( timestampsOfListEntriesToShow != null )
- timestampsOfListEntriesToShow.Add( uncollapsedLogEntriesTimestamps[i] );
- }
- }
- }
- }
- }
-
- recycledListView.DeselectSelectedLogItem();
- recycledListView.OnLogEntriesUpdated( true );
- ValidateScrollPosition();
- }
- public string GetAllLogs()
- {
-
- ProcessQueuedLogs( queuedLogEntries.Count );
- int count = uncollapsedLogEntriesIndices.Count;
- int length = 0;
- int newLineLength = System.Environment.NewLine.Length;
- for( int i = 0; i < count; i++ )
- {
- DebugLogEntry entry = collapsedLogEntries[uncollapsedLogEntriesIndices[i]];
- length += entry.logString.Length + entry.stackTrace.Length + newLineLength * 3;
- }
- if( uncollapsedLogEntriesTimestamps != null )
- length += count * 12;
- length += 100;
- StringBuilder sb = new StringBuilder( length );
- for( int i = 0; i < count; i++ )
- {
- DebugLogEntry entry = collapsedLogEntries[uncollapsedLogEntriesIndices[i]];
- if( uncollapsedLogEntriesTimestamps != null )
- {
- uncollapsedLogEntriesTimestamps[i].AppendTime( sb );
- sb.Append( ": " );
- }
- sb.AppendLine( entry.logString ).AppendLine( entry.stackTrace ).AppendLine();
- }
- return sb.ToString();
- }
- private void SaveLogsToFile()
- {
- SaveLogsToFile( Path.Combine( Application.persistentDataPath, System.DateTime.Now.ToString( "dd-MM-yyyy--HH-mm-ss" ) + ".txt" ) );
- }
- private void SaveLogsToFile( string filePath )
- {
- File.WriteAllText( filePath, GetAllLogs() );
- Debug.Log( "Logs saved to: " + filePath );
- }
-
- private void CheckScreenCutout()
- {
- if( !avoidScreenCutout )
- return;
- #if UNITY_2017_2_OR_NEWER && ( UNITY_EDITOR || UNITY_ANDROID || UNITY_IOS )
-
- int screenHeight = Screen.height;
- float safeYMax = Screen.safeArea.yMax;
- if( safeYMax < screenHeight - 1 )
- {
-
- float cutoutPercentage = ( screenHeight - safeYMax ) / Screen.height;
- float cutoutLocalSize = cutoutPercentage * canvasTR.rect.height;
- logWindowTR.anchoredPosition = new Vector2( 0f, -cutoutLocalSize );
- logWindowTR.sizeDelta = new Vector2( 0f, -cutoutLocalSize );
- }
- else
- {
- logWindowTR.anchoredPosition = Vector2.zero;
- logWindowTR.sizeDelta = Vector2.zero;
- }
- #endif
- }
- #if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL
- private IEnumerator ActivateCommandInputFieldCoroutine()
- {
-
- yield return null;
- commandInputField.ActivateInputField();
- yield return null;
- commandInputField.MoveTextEnd( false );
- }
- #endif
-
- internal void PoolLogItem( DebugLogItem logItem )
- {
- logItem.CanvasGroup.alpha = 0f;
- logItem.CanvasGroup.blocksRaycasts = false;
- pooledLogItems.Add( logItem );
- }
-
- internal DebugLogItem PopLogItem()
- {
- DebugLogItem newLogItem;
-
-
- if( pooledLogItems.Count > 0 )
- {
- newLogItem = pooledLogItems[pooledLogItems.Count - 1];
- pooledLogItems.RemoveAt( pooledLogItems.Count - 1 );
- newLogItem.CanvasGroup.alpha = 1f;
- newLogItem.CanvasGroup.blocksRaycasts = true;
- }
- else
- {
- newLogItem = (DebugLogItem) Instantiate( logItemPrefab, logItemsContainer, false );
- newLogItem.Initialize( recycledListView );
- }
- return newLogItem;
- }
- }
- }
|