< Summary

Class:GDX.Developer.Console
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Developer/Console.cs
Covered lines:48
Uncovered lines:177
Coverable lines:225
Total lines:360
Line coverage:21.3% (48 of 225)
Covered branches:0
Total branches:0
Covered methods:4
Total methods:25
Method coverage:16% (4 of 25)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Console()0%110100%
RegisterCommand(...)0%220100%
RegisterVariable(...)0%6200%
UnregisterVariable(...)0%2100%
UnregisterVariable(...)0%2100%
HasVariable(...)0%2100%
GetVariableCount()0%2100%
UnregisterCommand(...)0%2100%
UnregisterCommand(...)0%2100%
GetAccessLevel()0%2100%
FilterStartsWith(...)0%12300%
FilterContains(...)0%12300%
GetCommandAutoCompleteSuggestions(...)0%42600%
GetCommand(...)0%12300%
GetVariable(...)0%12300%
GetCommandKeywordsCopy()0%2100%
GetVariableNamesCopy()0%2100%
GetCommandKeywordsEnumerator()0%2100%
GetPreviousCommand(...)0%12300%
QueueCommand(...)0%1101000%
SetAccessLevel(...)0%2100%
Tick(...)0%8.033017.65%
Initialize()0%4.064084.38%

File(s)

./Packages/com.dotbunny.gdx/GDX/Developer/Console.cs

#LineLine coverage
 1// Copyright (c) 2020-2022 dotBunny Inc.
 2// dotBunny licenses this file to you under the BSL-1.0 license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System;
 6using System.Collections.Generic;
 7using System.Text;
 8using GDX.Collections.Generic;
 9using GDX.Developer.ConsoleCommands;
 10using UnityEditor;
 11using UnityEngine;
 12using UnityEngine.Networking.PlayerConnection;
 13
 14namespace GDX.Developer
 15{
 16#if UNITY_2022_2_OR_NEWER
 17    public static class Console
 18    {
 19        public enum ConsoleAccessLevel
 20        {
 21            Anonymous = -1,
 22            User = 0,
 23            Superuser = 1,
 24            Developer = 2
 25        }
 26
 227        static ConsoleAccessLevel s_AccessLevel = ConsoleAccessLevel.Developer;
 228        static CircularBuffer<string> s_CommandHistory = new CircularBuffer<string>(50);
 229        static readonly Queue<ConsoleCommandBase> k_CommandBuffer = new Queue<ConsoleCommandBase>(50);
 230        static StringKeyDictionary<ConsoleCommandBase>
 31            s_KnownCommands = new StringKeyDictionary<ConsoleCommandBase>(50);
 232        static StringKeyDictionary<ConsoleVariableBase> s_ConsoleVariables =
 33            new StringKeyDictionary<ConsoleVariableBase>(
 34                50);
 35
 236        static readonly List<string> k_KnownCommandsList = new List<string>(50);
 237        static readonly List<string> k_KnownVariablesList = new List<string>(50);
 38        public static ConsoleLog Log;
 39
 240        static int s_HintCacheLength = 0;
 41
 042        public static int PreviousCommandCount => s_CommandHistory.Count;
 043        public static int CommandBufferCount => k_CommandBuffer.Count;
 44
 45
 246        static SimpleWatch s_BufferCountWatch = new SimpleWatch("console.buffer", "Buffered Commands",
 047            () => CommandBufferCount.ToString(), false);
 48
 49        public static void RegisterCommand(ConsoleCommandBase command)
 13950        {
 13951            string keyword = command.GetKeyword();
 13952            if (!s_KnownCommands.ContainsKey(keyword))
 4453            {
 4454                s_KnownCommands.AddWithExpandCheck(keyword, command);
 4455                k_KnownCommandsList.Add(keyword);
 4456                s_HintCacheLength++;
 4457            }
 13958        }
 59
 60        public static void RegisterVariable(ConsoleVariableBase variable)
 061        {
 062            string name = variable.GetName();
 063            if (s_ConsoleVariables.ContainsKey(name))
 064            {
 065                return;
 66            }
 67
 068            s_ConsoleVariables.AddWithExpandCheck(name, variable);
 069            k_KnownVariablesList.Add(name);
 070            s_HintCacheLength++;
 071        }
 72
 73        public static void UnregisterVariable(ConsoleVariableBase variable)
 074        {
 075            UnregisterVariable(variable.GetName());
 076        }
 77
 78        public static void UnregisterVariable(string name)
 079        {
 080            k_KnownVariablesList.Remove(name);
 081            s_ConsoleVariables.TryRemove(name);
 082            s_HintCacheLength--;
 083        }
 84
 85        public static bool HasVariable(string name)
 086        {
 087            return k_KnownVariablesList.Contains(name);
 088        }
 89
 90        public static int GetVariableCount()
 091        {
 092            return k_KnownVariablesList.Count;
 093        }
 94
 95        public static void UnregisterCommand(ConsoleCommandBase command)
 096        {
 097            UnregisterCommand(command.GetKeyword());
 098        }
 99
 100        public static void UnregisterCommand(string keyword)
 0101        {
 0102            k_KnownCommandsList.Remove(keyword);
 0103            s_KnownCommands.TryRemove(keyword);
 0104        }
 105
 106        public static ConsoleAccessLevel GetAccessLevel()
 0107        {
 0108            return s_AccessLevel;
 0109        }
 110
 111
 112        static string[] FilterStartsWith(string filter, string[] set)
 0113        {
 0114            int count = set.Length;
 0115            SimpleList<string> possible = new SimpleList<string>(count);
 0116            for (int i = 0; i < count; i++)
 0117            {
 0118                string evalString = set[i];
 0119                if (evalString.StartsWith(filter))
 0120                {
 0121                    possible.AddUnchecked(evalString);
 0122                }
 0123            }
 0124            possible.Compact();
 0125            return possible.Array;
 0126        }
 127
 128        static string[] FilterContains(string filter, string[] set)
 0129        {
 0130            int count = set.Length;
 0131            SimpleList<string> possible = new SimpleList<string>(count);
 0132            for (int i = 0; i < count; i++)
 0133            {
 0134                string evalString = set[i];
 0135                if (evalString.Contains(filter))
 0136                {
 0137                    possible.AddUnchecked(evalString);
 0138                }
 0139            }
 0140            possible.Compact();
 0141            return possible.Array;
 0142        }
 143
 144
 145        public static string[] GetCommandAutoCompleteSuggestions(string hint, string[] existingSet = null)
 0146        {
 0147            if (existingSet != null)
 0148            {
 0149                return FilterStartsWith(hint, existingSet);
 150            }
 151
 0152            SimpleList<string> possibleCommands = new SimpleList<string>(s_HintCacheLength);
 0153            int commandCount = k_KnownCommandsList.Count;
 0154            for (int i = 0; i < commandCount; i++)
 0155            {
 0156                string evalString = k_KnownCommandsList[i];
 0157                if (evalString.StartsWith(hint))
 0158                {
 0159                    possibleCommands.AddUnchecked(evalString);
 0160                }
 0161            }
 162
 0163            int variableCount = k_KnownVariablesList.Count;
 0164            for (int i = 0; i < variableCount; i++)
 0165            {
 0166                string evalString = k_KnownVariablesList[i];
 0167                if (evalString.StartsWith(hint))
 0168                {
 0169                    possibleCommands.AddUnchecked(evalString);
 0170                }
 0171            }
 0172            possibleCommands.Compact();
 0173            return possibleCommands.Array;
 0174        }
 175
 176        public static ConsoleCommandBase GetCommand(string keyword)
 0177        {
 0178            return s_KnownCommands.ContainsKey(keyword) ? s_KnownCommands[keyword] : null;
 0179        }
 180
 181        public static ConsoleVariableBase GetVariable(string name)
 0182        {
 0183            return s_ConsoleVariables.ContainsKey(name) ? s_ConsoleVariables[name] : null;
 0184        }
 185
 186        public static string[] GetCommandKeywordsCopy()
 0187        {
 0188            return k_KnownCommandsList.ToArray();
 0189        }
 190
 191        public static string[] GetVariableNamesCopy()
 0192        {
 0193            return k_KnownVariablesList.ToArray();
 0194        }
 195
 196
 197
 198        public static List<string>.Enumerator GetCommandKeywordsEnumerator()
 0199        {
 0200            return k_KnownCommandsList.GetEnumerator();
 0201        }
 202
 203        public static string GetPreviousCommand(int offset = 0)
 0204        {
 0205            int count = s_CommandHistory.Count;
 0206            if (count == 0)
 0207            {
 0208                return string.Empty;
 209            }
 210
 0211            if (offset >= count)
 0212            {
 0213                return s_CommandHistory[count - 1];
 214            }
 215
 0216            return s_CommandHistory[count - 1 - offset];
 0217        }
 218
 219        public static bool QueueCommand(string commandString)
 0220        {
 0221            string safeCommand = commandString.Trim();
 0222            if (string.IsNullOrEmpty(safeCommand))
 0223            {
 0224                return false;
 225            }
 226
 227            // Add to history even if bad
 0228            s_CommandHistory.Add(safeCommand);
 229
 230            // We do not split passed the command as to ensure the execution cost is passed down to the actual command
 231            // if subsequent args need to be processed.
 0232            string[] split = safeCommand.Split(' ', 2, StringSplitOptions.RemoveEmptyEntries);
 233
 234            // Check if its a valid command
 0235            ConsoleCommandBase command = GetCommand(split[0]);
 0236            if (command != null)
 0237            {
 0238                if (command.GetAccessLevel() > s_AccessLevel)
 0239                {
 0240                    Debug.LogWarning($"Invalid Command: {split[0]} - A higher access level is required.");
 0241                    return false;
 242                }
 243
 0244                ConsoleCommandBase workUnit = command.GetInstance(split.Length > 1 ? split[1].Trim() : null);
 0245                if (workUnit == null)
 0246                {
 0247                    Debug.LogWarning($"Invalid Command: {split[0]} - Unable to generate work unit.");
 0248                    return false;
 249                }
 250
 0251                k_CommandBuffer.Enqueue(workUnit);
 0252                return true;
 253            }
 254
 255            // Check for console variables
 0256            ConsoleVariableBase variable = GetVariable(split[0]);
 0257            if (variable != null)
 0258            {
 0259                if (split.Length > 1) // Set Value
 0260                {
 0261                    if (variable.GetAccessLevel() > s_AccessLevel)
 0262                    {
 0263                        Debug.LogWarning($"Unable to set {split[0]} - A higher access level is required.");
 0264                        return false;
 265                    }
 266
 0267                    variable.SetValueFromString(split[1].Trim());
 0268                    Debug.Log($"{variable.GetName()} is now '{variable.GetCurrentValueAsString()}'");
 0269                }
 270                else // Echo
 0271                {
 0272                    Debug.Log($"{variable.GetName()} is '{variable.GetCurrentValueAsString()}' [{variable.GetDefaultValu
 0273                }
 274
 0275                return true;
 276            }
 277
 0278            Debug.LogWarning($"Invalid Command: {split[0]}");
 0279            return false;
 0280        }
 281
 282        public static void SetAccessLevel(ConsoleAccessLevel level)
 0283        {
 0284            s_AccessLevel = level;
 0285        }
 286
 287        public static void Tick(float deltaTime)
 4405288        {
 4405289            while (k_CommandBuffer.Count > 0)
 0290            {
 0291                ConsoleCommandBase command = k_CommandBuffer.Peek();
 292
 293                // We evaluate inside of a try-catch to capture the exception and flush the command buffer.
 294                try
 0295                {
 0296                    if (!command.Evaluate(deltaTime))
 0297                    {
 0298                        break;
 299                    }
 0300                }
 0301                catch (Exception e)
 0302                {
 0303                    Debug.LogException(e);
 0304                    k_CommandBuffer.Clear();
 0305                    break;
 306                }
 307
 0308                k_CommandBuffer.Dequeue();
 0309            }
 4405310        }
 311
 312#if UNITY_EDITOR
 313        [InitializeOnLoadMethod]
 314#endif
 315        [RuntimeInitializeOnLoadMethod]
 316        static void Initialize()
 7317        {
 7318            if (!Config.EnvironmentDeveloperConsole) return;
 319
 7320            Log = new ConsoleLog();
 321
 322            // We preregister a bunch of commands to be optimal
 7323            RegisterCommand(new HelpConsoleCommand());
 7324            RegisterCommand(new ShowConsoleCommand());
 7325            RegisterCommand(new HideConsoleCommand());
 7326            RegisterCommand(new QuitConsoleCommand());
 7327            RegisterCommand(new ExecConsoleCommand());
 7328            RegisterCommand(new PlayerLoopConsoleCommand());
 7329            RegisterCommand(new VersionConsoleCommand());
 7330            RegisterCommand(new WaitConsoleCommand());
 7331            RegisterCommand(new SceneListConsoleCommand());
 7332            RegisterCommand(new SceneLoadConsoleCommand());
 7333            RegisterCommand(new SceneWaitConsoleCommand());
 7334            RegisterCommand(new InputKeyPressConsoleCommand());
 7335            RegisterCommand(new GarbageCollectionConsoleCommand());
 7336            RegisterCommand(new BuildVerificationTestConsoleCommand());
 7337            RegisterCommand(new ConsoleVariablesConsoleCommand());
 7338            RegisterCommand(new WatchConsoleCommand());
 7339            RegisterCommand(new WatchAllConsoleCommand());
 7340            RegisterCommand(new WatchListConsoleCommand());
 7341            RegisterCommand(new ScreenCaptureConsoleCommand());
 342
 343            // We are going to look at the arguments
 7344            if (CommandLineParser.Arguments.ContainsKey("exec"))
 0345            {
 346                // We want to make sure that we have everything loading and ready before we actually execute a script
 0347                QueueCommand("scene.wait");
 0348                QueueCommand($"exec {CommandLineParser.Arguments["exec"]}");
 0349            }
 350
 351            // Register for remote connection from editor response
 7352            PlayerConnection.instance.Register(ConsoleCommandBase.PlayerConnectionGuid,
 0353                args => QueueCommand(Encoding.UTF8.GetString(args.data)));
 354
 7355            ConsoleVariableSettings.UpdateFromFile();
 7356            WatchSettings.UpdateFromFile();
 7357        }
 358    }
 359#endif // UNITY_2022_2_OR_NEWER
 360}

Coverage by test methods






























Methods/Properties

Console()
PreviousCommandCount()
CommandBufferCount()
RegisterCommand(GDX.Developer.ConsoleCommandBase)
RegisterVariable(GDX.Developer.ConsoleVariableBase)
UnregisterVariable(GDX.Developer.ConsoleVariableBase)
UnregisterVariable(System.String)
HasVariable(System.String)
GetVariableCount()
UnregisterCommand(GDX.Developer.ConsoleCommandBase)
UnregisterCommand(System.String)
GetAccessLevel()
FilterStartsWith(System.String, System.String[])
FilterContains(System.String, System.String[])
GetCommandAutoCompleteSuggestions(System.String, System.String[])
GetCommand(System.String)
GetVariable(System.String)
GetCommandKeywordsCopy()
GetVariableNamesCopy()
GetCommandKeywordsEnumerator()
GetPreviousCommand(System.Int32)
QueueCommand(System.String)
SetAccessLevel(GDX.Developer.Console/ConsoleAccessLevel)
Tick(System.Single)
Initialize()