Cogwheel/src/COGWHEEL.cs
Chris Bell 8ffedd6ba9 - Added more public CommandsManager access methods to the COGWHEEL static class
- Ability to add custom parsers to the CommandManager with AddCustomerParser(Type, Func<string, object>)
- Added two custom parsers from the COGWHEEL class: `System.Numerics.Vector2` and `System.Numerics.Vector3`
2025-01-03 19:12:19 -06:00

294 lines
8.8 KiB
C#

using System;
using System.Linq;
using System.Numerics;
using System.Reflection;
namespace Cogwheel;
/// <summary>
/// Static class for interacting with the Cogwheel system
/// </summary>
public static class COGWHEEL
{
private static CommandsManager _commandsManager;
private static ICogwheelConsole _console;
public static bool UseBuiltInCommands { get; set; } = true;
/// <summary>
/// Initializes the Cogwheel system
/// </summary>
/// <param name="commandsManager"></param>
/// <param name="console"></param>
public static void Initialize(CommandsManager commandsManager, ICogwheelConsole console)
{
_console = console;
_commandsManager = commandsManager;
InitializeCustomParsers();
_commandsManager.Initialize(_console);
_console.Initialize(_commandsManager);
}
// == Public static methods for the CommandsManager == //
/// <summary>
/// Runs a command
/// </summary>
/// <param name="input"></param>
public static void RunCommand(string input)
{
_commandsManager.RunCommand(input);
}
/// <summary>
/// Registers an object with the CommandsManager for non-static commands
/// </summary>
/// <param name="obj"></param>
public static void RegisterObject(object obj)
{
_commandsManager.RegisterObject(obj);
}
// == Public static methods for the Console == //
/// <summary>
/// Logs a message to the console
/// </summary>
/// <param name="message"></param>
public static void Log(string message)
{
_console.Log(message);
}
/// <summary>
/// Logs an error message to the console
/// </summary>
/// <param name="message"></param>
public static void LogError(string message)
{
_console.LogError(message);
}
/// <summary>
/// Logs a warning message to the console
/// </summary>
/// <param name="message"></param>
public static void LogWarning(string message)
{
_console.LogWarning(message);
}
/// <summary>
/// Writes a message to the console
/// </summary>
/// <param name="message"></param>
public static void Write(string message)
{
_console.Write(message);
}
/// <summary>
/// Sets the context for the CommandsManager
/// </summary>
/// <param name="obj"></param>
public static void SetContext(object obj)
{
_commandsManager.SetContext(obj);
}
/// <summary>
/// Sets the context for the CommandsManager by GUID
/// </summary>
/// <param name="guid"></param>
public static void SetContext(Guid guid)
{
_commandsManager.SetContext(guid);
}
/// <summary>
/// Sets the context for the CommandsManager by GUID string
/// </summary>
/// <param name="guidString"></param>
public static void SetContext(string guidString)
{
_commandsManager.SetContext(guidString);
}
// == Built-in commands == //
/// <summary>
/// Quit the Cogwheel console
/// </summary>
[Command(Name = "quit", Description = "Quits the Cogwheel console.")]
public static void QuitCogwheelConsole()
{
_console.Exit();
}
/// <summary>
/// Clears the console
/// </summary>
[Command(Name = "clear", Description = "Clears the console.")]
public static void ClearConsole()
{
_console.ClearConsole();
}
/// <summary>
/// Shows the description and usage of a given command
/// </summary>
/// <param name="commandName"></param>
[Command(Name = "help", Description = "Gets usage for given command.")]
public static void ShowHelp(string commandName)
{
ICommand? command = _commandsManager.GetCommandByName(commandName);
if (command is null)
{
_console.LogError($"Command error: '{commandName}' is not a command.");
return;
}
_console.Log($"-- Command Usage For {commandName} --\n" +
$"Description: {command.Description}\n" +
$"Usage: {_commandsManager.GetCommandUsage(command)}");
}
/// <summary>
/// Lists all available commands
/// </summary>
[Command(Name = "list", Description = "Lists all available commands.")]
public static void ListCommands()
{
foreach (var command in _commandsManager.Commands)
{
Write($"{_commandsManager.GetCommandUsage(command.Value)}");
}
}
/// <summary>
/// Logs the current context type and GUID
/// </summary>
[Command(Name = "what", Description = "Prints the current context.")]
public static void ShowCurrentContext()
{
if (_commandsManager.CurrentContext is null)
{
Log("No context set.");
return;
}
_console.Log($"Current context: {_commandsManager.CurrentContext.GetType()} : {_commandsManager.CurrentContextGuid}");
}
/// <summary>
/// Adds an assembly to the CommandsManager for command discovery
/// </summary>
/// <param name="assembly"></param>
public static void AddAssembly(Assembly assembly)
{
_commandsManager.AddAssembly(assembly);
}
/// <summary>
/// Removes an assembly from the CommandsManager
/// </summary>
/// <param name="assembly"></param>
public static void RemoveAssembly(Assembly assembly)
{
_commandsManager.RemoveAssembly(assembly);
}
/// <summary>
/// Adds a custom parser for a given type
/// </summary>
/// <param name="type"></param>
/// <param name="parser"></param>
public static void AddCustomParser(Type type, Func<string, object> parser)
{
_commandsManager.AddCustomParser(type, parser);
}
/// <summary>
/// Logs all registered objects and their GUIDs, optionally filtered by type
/// </summary>
/// <param name="typeName"></param>
[Command(Name = "find", Description = "Lists available registered objects to select from.")]
private static void FindAllContextsFromRegisteredObjects(string typeName = "")
{
var registeredObjects = _commandsManager.RegisteredObjectInstances;
var filteredObjects = string.IsNullOrEmpty(typeName)
? registeredObjects
: registeredObjects.Where(kvp => kvp.Value.GetType().FullName == typeName).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
if (!filteredObjects.Any())
{
LogError($"No registered objects found for type '{typeName}'");
return;
}
Log("Available registered objects:");
foreach (var (guid, obj) in filteredObjects)
{
Write($"- {obj.GetType().FullName} : {guid}");
}
}
/// <summary>
/// Sets the context to the specified registered object by GUID
/// </summary>
/// <param name="guidString"></param>
[Command(Name = "set", Description = "Sets the context to the specified registered object.")]
private static void SetContextFromGuid(string guidString)
{
SetContext(guidString);
Log($"Set context to {_commandsManager.CurrentContext?.GetType().FullName} : {_commandsManager.CurrentContextGuid}");
}
/// <summary>
/// Initializes custom parsers for the Cogwheel system
/// </summary>
/// <exception cref="FormatException"></exception>
private static void InitializeCustomParsers()
{
// Add custom parser for Vector2
_commandsManager.AddCustomParser(typeof(Vector2), s =>
{
s = s.Trim('(', ')');
var parts = s.Split(',');
if (parts.Length != 2)
{
throw new FormatException("Input string must have exactly three components separated by commas.");
}
if (!float.TryParse(parts[0].Trim(), out float x) ||
!float.TryParse(parts[1].Trim(), out float y))
{
throw new FormatException("Input string contains invalid float values.");
}
return new Vector2(x, y);
});
// Add custom parser for Vector3
_commandsManager.AddCustomParser(typeof(Vector3), s =>
{
s = s.Trim('(', ')');
var parts = s.Split(',');
if (parts.Length != 3)
{
throw new FormatException("Input string must have exactly three components separated by commas.");
}
if (!float.TryParse(parts[0].Trim(), out float x) ||
!float.TryParse(parts[1].Trim(), out float y) ||
!float.TryParse(parts[2].Trim(), out float z))
{
throw new FormatException("Input string contains invalid float values.");
}
return new Vector3(x, y, z);
});
}
}