289 lines
8.8 KiB
C#
289 lines
8.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Reflection;
|
|
|
|
namespace Cabrito
|
|
{
|
|
[AttributeUsage(AttributeTargets.All)]
|
|
public class ConsoleVariableAttribute : Attribute
|
|
{
|
|
public string name;
|
|
|
|
public ConsoleVariableAttribute(string name)
|
|
{
|
|
this.name = name;
|
|
}
|
|
}
|
|
|
|
[AttributeUsage(AttributeTargets.All)]
|
|
public class ConsoleCommandAttribute : Attribute
|
|
{
|
|
public string name;
|
|
|
|
public ConsoleCommandAttribute(string name)
|
|
{
|
|
this.name = name;
|
|
}
|
|
}
|
|
|
|
internal struct ConsoleVariable
|
|
{
|
|
private FieldInfo field;
|
|
|
|
public ConsoleVariable(FieldInfo field)
|
|
{
|
|
this.field = field;
|
|
}
|
|
|
|
public string GetValueString()
|
|
{
|
|
if (field.FieldType != typeof(string))
|
|
throw new Exception("cvar is not type of string");
|
|
|
|
return (string)field.GetValue(null);
|
|
}
|
|
|
|
public void SetValue(string value)
|
|
{
|
|
var type = field.FieldType;
|
|
if (type == typeof(string))
|
|
field.SetValue(null, value);
|
|
else
|
|
throw new Exception("Unsupported type for SetValue: " + type.Name);
|
|
}
|
|
}
|
|
|
|
internal struct ConsoleCommand
|
|
{
|
|
private MethodInfo method;
|
|
|
|
public ConsoleCommand(MethodInfo method)
|
|
{
|
|
this.method = method;
|
|
}
|
|
|
|
public void Invoke(params object[] parameters)
|
|
{
|
|
method.Invoke(null, parameters);
|
|
}
|
|
}
|
|
|
|
public static class Console
|
|
{
|
|
private static ConsoleScriptBase scriptInstance = null;
|
|
|
|
// Returns if Console window open right now.
|
|
public static bool IsOpen { get; internal set; }
|
|
|
|
// For debugging only: Returns true when Console was not closed during the same frame.
|
|
// Needed when Escape-key both closes the console and exits the game.
|
|
public static bool IsSafeToQuit { get { return stopwatch.Elapsed.TotalSeconds > 0.1; } }
|
|
private static Stopwatch stopwatch = Stopwatch.StartNew();
|
|
|
|
// Called when Console is opened.
|
|
public static Action OnOpen;
|
|
|
|
// Called when Console is closed.
|
|
public static Action OnClose;
|
|
|
|
public static bool ShowExecutedLines = true;
|
|
public static string LinePrefix { get; internal set; } = "]";
|
|
|
|
|
|
private static List<string> consoleLines = new List<string>();
|
|
private static Dictionary<string, ConsoleCommand> consoleCommands = new Dictionary<string, ConsoleCommand>();
|
|
private static Dictionary<string, ConsoleVariable> consoleVariables = new Dictionary<string, ConsoleVariable>();
|
|
|
|
// Initializes the Console system.
|
|
public static void Init()
|
|
{
|
|
consoleLines.Clear();
|
|
consoleCommands.Clear();
|
|
consoleVariables.Clear();
|
|
|
|
AppDomain currentDomain = AppDomain.CurrentDomain;
|
|
Assembly[] assemblies = currentDomain.GetAssemblies();
|
|
|
|
foreach (var assembly in assemblies)
|
|
{
|
|
// Skip common assemblies
|
|
var assemblyName = assembly.GetName().Name;
|
|
if (assemblyName == "System" ||
|
|
assemblyName.StartsWith("System.") ||
|
|
assemblyName.StartsWith("Mono.") ||
|
|
assemblyName == "mscorlib" ||
|
|
assemblyName == "Newtonsoft.Json" ||
|
|
assemblyName.StartsWith("FlaxEngine."))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
foreach (var type in assembly.GetTypes())
|
|
{
|
|
foreach (var method in type.GetMethods())
|
|
{
|
|
if (!method.IsStatic)
|
|
continue;
|
|
|
|
Attribute[] attributes = Attribute.GetCustomAttributes(method);
|
|
|
|
foreach (var attr in attributes)
|
|
{
|
|
if (attr is ConsoleCommandAttribute cmdAttribute)
|
|
{
|
|
//Console.Print("found cmd '" + cmdAttribute.name + "' bound to field '" + method.Name + "'");
|
|
var cmd = new ConsoleCommand(method);
|
|
consoleCommands.Add(cmdAttribute.name.ToLower(), cmd);
|
|
}
|
|
}
|
|
}
|
|
foreach (var field in type.GetFields())
|
|
{
|
|
if (!field.IsStatic)
|
|
continue;
|
|
|
|
Attribute[] attributes = Attribute.GetCustomAttributes(field);
|
|
|
|
foreach (var attr in attributes)
|
|
{
|
|
if (attr is ConsoleVariableAttribute cvarAttribute)
|
|
{
|
|
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
|
|
var cvar = new ConsoleVariable(field);
|
|
consoleVariables.Add(cvarAttribute.name.ToLower(), cvar);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Register script for handling the Console frontend.
|
|
internal static void RegisterConsoleScript(ConsoleScriptBase instance)
|
|
{
|
|
if (scriptInstance == instance)
|
|
return;
|
|
|
|
scriptInstance = instance;
|
|
OnOpen += instance.OnConsoleOpen;
|
|
OnClose += instance.OnConsoleClose;
|
|
|
|
foreach (var line in consoleLines)
|
|
scriptInstance.AddLine(line);
|
|
}
|
|
|
|
/// Unregister already registered Console script.
|
|
internal static void UnregisterConsoleScript(ConsoleScriptBase instance)
|
|
{
|
|
if (scriptInstance != instance)
|
|
return;
|
|
|
|
Close();
|
|
|
|
scriptInstance = null;
|
|
OnOpen -= instance.OnConsoleOpen;
|
|
OnClose -= instance.OnConsoleClose;
|
|
}
|
|
|
|
public static IReadOnlyCollection<string> GetLines()
|
|
{
|
|
return consoleLines.AsReadOnly();
|
|
}
|
|
|
|
// Echoes text to Console.
|
|
public static void Print(string text)
|
|
{
|
|
consoleLines.Add(text);
|
|
scriptInstance?.AddLine(text);
|
|
}
|
|
|
|
// Echoes warning text to Console.
|
|
public static void PrintWarning(string text)
|
|
{
|
|
consoleLines.Add(text);
|
|
scriptInstance?.AddLine(text);
|
|
}
|
|
|
|
// Echoes error text to Console.
|
|
public static void PrintError(string text)
|
|
{
|
|
consoleLines.Add(text);
|
|
scriptInstance?.AddLine(text);
|
|
}
|
|
|
|
// Echoes developer/debug text to Console.
|
|
public static void PrintDebug(string text)
|
|
{
|
|
consoleLines.Add(text);
|
|
scriptInstance?.AddLine(text);
|
|
}
|
|
|
|
// Opens the Console.
|
|
public static void Open()
|
|
{
|
|
if (IsOpen)
|
|
return;
|
|
|
|
IsOpen = true;
|
|
OnOpen?.Invoke();
|
|
}
|
|
|
|
// Closes the Console;
|
|
public static void Close()
|
|
{
|
|
if (!IsOpen)
|
|
return;
|
|
|
|
IsOpen = false;
|
|
OnClose?.Invoke();
|
|
|
|
stopwatch.Restart();
|
|
}
|
|
|
|
public static void ClearInput()
|
|
{
|
|
scriptInstance?.SetInput("");
|
|
}
|
|
|
|
public static void Execute(string str)
|
|
{
|
|
str = str.Trim();
|
|
|
|
if (ShowExecutedLines)
|
|
Console.Print(LinePrefix + str);
|
|
|
|
string[] strs = str.Split(' ');
|
|
string execute = strs[0];
|
|
string value = strs.Length > 1 ? str.Substring(execute.Length + 1) : null;
|
|
|
|
//Console.PrintDebug("Executed '" + execute + "' with params: '" + value + "'");
|
|
|
|
if (consoleCommands.TryGetValue(execute, out ConsoleCommand cmd))
|
|
{
|
|
cmd.Invoke();
|
|
//Console.Print("Command bound to '" + execute + "' is '" + cmd.method.Name + "'");
|
|
}
|
|
else if (consoleVariables.TryGetValue(execute, out ConsoleVariable cvar))
|
|
{
|
|
if (value != null)
|
|
cvar.SetValue(value);
|
|
|
|
Console.Print("'" + execute + "' is '" + cvar.GetValueString() + "'");
|
|
}
|
|
else
|
|
Console.Print("Unknown command '" + execute + "'");
|
|
}
|
|
|
|
public static string GetVariable(string variableName)
|
|
{
|
|
if (consoleVariables.TryGetValue(variableName, out ConsoleVariable cvar))
|
|
{
|
|
string value = cvar.GetValueString();
|
|
return value;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
}
|