HKI Core
DebugConsole.cs
Go to the documentation of this file.
1 #pragma warning disable 0649
2 using UnityEngine;
3 using UnityEngine.UI;
4 using System.Text;
5 using System.Collections;
6 using System.Collections.Generic;
7 
8 namespace HKI.Core.Debuging
9 {
15  public class DebugConsole : MonoBehaviour
16  {
17  // Class
21  public class Command
22  {
23  // Delegate
24  public delegate void ConsoleCommandFunction(string[] parameters);
25 
26  // Public variables
27  public const string NoHelpString = "(no description)";
28 
29  // Private variables
30  ConsoleCommandFunction callback = null;
31  string name = null;
32  string paramsExample = null;
33  string help = null;
34 
35  // Getter
36  public ConsoleCommandFunction Callback { get { return callback; } }
37  public string Name { get { return name; } }
38  public string ParamsExample { get { return paramsExample; } }
39  public string Help { get { return help; } }
40 
41  // Constructor
42  public Command(string name, ConsoleCommandFunction callback, string help, string paramsExample)
43  {
44  this.callback = callback;
45  this.name = name;
46  this.paramsExample = paramsExample;
47  this.help = help;
48  }
49  }
50 
51  // Public variables
52  public static DebugConsole Instance { get; private set; }
53 
54  [SerializeField] DebugSystem DebugSystem = null;
55 
56  [SerializeField] Scrollbar Scrollbar = null;
57  [SerializeField] InputField CommandInputField = null;
58 
59  [SerializeField] Color EchoColor = new Color(0.2f, 0.2f, 0.2f, 1.0f);
60  [SerializeField] Color LogColor = Color.white;
61  [SerializeField] Color WarningColor = new Color(1.0f, 0.5f, 0.0f, 1.0f);
62  [SerializeField] Color ErrorColor = Color.red;
63  [SerializeField] Color CommandColor = Color.cyan;
64  [SerializeField] Color InvalidCommand = Color.magenta;
65 
66  [SerializeField] Text[] Texts;
67 
68  // Private variables
69  Queue<Text> textStack = new Queue<Text>();
70 
71  const string sizeStartString = "<size=10>";
72  const string sizeEndString = "</size>";
73 
74  Dictionary<string, Command> commands = new Dictionary<string, Command>();
75 
76  string[] seperators = new string[] { "| ", " | ", "|" };
77 
78  // Awake function
79  void Awake()
80  {
81  if(Instance == null)
82  Instance = this;
83  else
84  return;
85 
86  if(Texts != null)
87  {
88  for(int i = 0; i < Texts.Length; i++)
89  {
90  Texts[i].gameObject.SetActive(false);
91  textStack.Enqueue(Texts[i]);
92  }
93  }
94 
95  StartCoroutine(SetScrollPosition());
96 
97  Application.logMessageReceived += OnLogReceived;
98 
99  InitConsoleCommands();
100  }
101 
102  // OnDestroy
103  void OnDestroy()
104  {
105  if(Instance == this)
106  Instance = null;
107  else
108  return;
109 
110  Application.logMessageReceived -= OnLogReceived;
111  }
112 
113  // Interface functions
114  public void OnSubmit()
115  {
116  if(!string.IsNullOrEmpty(CommandInputField.text))
117  {
118  string command = CommandInputField.text;
119 
120  CommandInputField.text = "";
121  ValidateAndCallCommand(command);
122  }
123 
124  DebugSystem.StartCoroutine(SetScrollPosition());
125  }
126 
127  public void RegisterCommand(string name, Command.ConsoleCommandFunction callback, string help = Command.NoHelpString, string paramsExample = "")
128  {
129  if(string.IsNullOrEmpty(name))
130  {
131  Debug.LogError("You are trying to register a command but this command doesn't have a name.");
132  return;
133  }
134 
135  if(callback == null)
136  {
137  Debug.LogError("You are trying to register a command (" + name + ") but this commands callback function is null.");
138  return;
139  }
140 
141  string nameLower = name.ToLower();
142 
143  if (!commands.ContainsKey(nameLower))
144  commands.Add(nameLower, new Command(nameLower, callback, help, paramsExample));
145  else
146  Debug.LogError("You are trying to register a command (" + name + ") but this command already exists.");
147  }
148 
149  public void DeregisterCommand(string name)
150  {
151  if (string.IsNullOrEmpty(name))
152  {
153  Debug.LogError("You are trying to deregister a command but this command doesn't have a name.");
154  return;
155  }
156 
157  string nameLower = name.ToLower();
158 
159  if(commands.ContainsKey(nameLower))
160  commands.Remove(nameLower);
161  else
162  Debug.LogError("You are trying to deregister a command (" + name + ") but this command doesn't exists.");
163  }
164 
165  // Helper functions
166  void OnLogReceived(string logString, string stackTrace, LogType type)
167  {
168  StringBuilder sb = new StringBuilder();
169  sb.AppendLine(logString);
170  sb.Append(sizeStartString);
171  sb.Append(stackTrace.Remove(0, stackTrace.IndexOf('\n') + 1));
172  sb.Remove(sb.Length - 1, 1);
173  sb.Append(sizeEndString);
174 
175  switch(type)
176  {
177  case LogType.Log:
178  Print(LogColor, sb.ToString());
179  break;
180 
181  case LogType.Error:
182  case LogType.Exception:
183  case LogType.Assert:
184  Print(ErrorColor, sb.ToString());
185  break;
186 
187  case LogType.Warning:
188  Print(WarningColor, sb.ToString());
189  break;
190  }
191 
192  DebugSystem.StartCoroutine(SetScrollPosition());
193  }
194 
195  void Print(Color color, string msg)
196  {
197  Text text = textStack.Dequeue();
198  text.text = msg;
199  text.color = color;
200  text.transform.SetAsLastSibling();
201  text.gameObject.SetActive(true);
202  textStack.Enqueue(text);
203  }
204 
205  void ValidateAndCallCommand(string fullCommand)
206  {
207  int openParenteciesIndex = fullCommand.IndexOf('(');
208  if(openParenteciesIndex >= 0 && fullCommand[fullCommand.Length - 1] != ')')
209  {
210  Print(InvalidCommand, fullCommand);
211  return;
212  }
213 
214  string command = openParenteciesIndex >= 0 ? fullCommand.Remove(openParenteciesIndex).ToLower() : fullCommand.ToLower();
215 
216  if(string.IsNullOrEmpty(command) || !commands.ContainsKey(command))
217  {
218  Print(InvalidCommand, fullCommand);
219  return;
220  }
221 
222  string[] parameters = openParenteciesIndex >= 0 ? fullCommand.Substring(openParenteciesIndex + 1, fullCommand.Length - openParenteciesIndex - 2).Split(seperators, System.StringSplitOptions.None) : null;
223 
224  Print(CommandColor, fullCommand);
225 
226  commands[command].Callback(parameters);
227  }
228 
230  {
231  RegisterCommand("Help", Help, "Displays all commands and help information for console commands when they are available.");
232  RegisterCommand("Clear", Clear, "Clears the console history.");
233  RegisterCommand("Cls", Clear, "Clears the console history (alias for Clear)");
234  RegisterCommand("Echo", Echo, "Writes <string> message to the console", "<string> message");
235  RegisterCommand("Print", Echo, "Writes <string> message to the console (alias for echo)", "<string> message");
236  RegisterCommand("QuitGame", Quit, "Quit the game.");
237  RegisterCommand("Quit Game", Quit, "Quit the game.");
238 
239  RegisterCommand("Log", Debug.Log, "Log a msg to the console.", "string");
240  }
241 
242  void Clear(string[] parameters)
243  {
244  if (Texts != null)
245  {
246  for (int i = 0; i < Texts.Length; i++)
247  Texts[i].gameObject.SetActive(false);
248  }
249  }
250 
251  void Help(string[] parameters)
252  {
253  StringBuilder sb = new StringBuilder("<color=#ffffff>Commands:</color>");
254  foreach(Command cmd in commands.Values)
255  {
256  sb.Append("\n<color=#ffffff>> ");
257  sb.Append(cmd.Name);
258  sb.Append("(");
259  sb.Append(cmd.ParamsExample);
260  sb.Append(")</color>\n ");
261  sb.Append(cmd.Help);
262  }
263 
264  Print(EchoColor, sb.ToString());
265  }
266 
267  void Echo(string[] parameters)
268  {
269  if(parameters != null && parameters.Length == 1)
270  Print(EchoColor, "Echo: " + parameters[0]);
271  }
272 
273  void Quit(string[] parameters)
274  {
275  Application.Quit();
276  }
277 
278  IEnumerator SetScrollPosition()
279  {
280  yield return null;
281 
282  if (Scrollbar != null)
283  Scrollbar.value = 0.0f;
284  }
285  }
286 }
void Clear(string[] parameters)
void DeregisterCommand(string name)
void ValidateAndCallCommand(string fullCommand)
delegate void ConsoleCommandFunction(string[] parameters)
void OnLogReceived(string logString, string stackTrace, LogType type)
void Help(string[] parameters)
void Print(Color color, string msg)
void Quit(string[] parameters)
MonoBehaviour for the debugging console
Definition: DebugConsole.cs:15
void Echo(string[] parameters)
Command(string name, ConsoleCommandFunction callback, string help, string paramsExample)
Definition: DebugConsole.cs:42
The DebugSystem controlls the pannel which includes the DebuConsole, SystemInfo, MemoryInfo and FPSIn...
Definition: DebugSystem.cs:12
void RegisterCommand(string name, Command.ConsoleCommandFunction callback, string help=Command.NoHelpString, string paramsExample="")
This command class binds all data related so it can be executed by the DebugConsole ...
Definition: DebugConsole.cs:21