using System;
using System.Linq;
using System.Numerics;
using System.Reflection;
namespace Cogwheel;
///
/// Static class for interacting with the Cogwheel system
///
public static class COGWHEEL
{
private static CommandsManager _commandsManager;
private static ICogwheelConsole _console;
public static bool UseBuiltInCommands { get; set; } = true;
///
/// Initializes the Cogwheel system
///
///
///
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 == //
///
/// Runs a command
///
///
public static void RunCommand(string input)
{
_commandsManager.RunCommand(input);
}
///
/// Registers an object with the CommandsManager for non-static commands
///
///
public static void RegisterObject(object obj)
{
_commandsManager.RegisterObject(obj);
}
// == Public static methods for the Console == //
///
/// Logs a message to the console
///
///
public static void Log(string message)
{
_console.Log(message);
}
///
/// Logs an error message to the console
///
///
public static void LogError(string message)
{
_console.LogError(message);
}
///
/// Logs a warning message to the console
///
///
public static void LogWarning(string message)
{
_console.LogWarning(message);
}
///
/// Writes a message to the console
///
///
public static void Write(string message)
{
_console.Write(message);
}
///
/// Sets the context for the CommandsManager
///
///
public static void SetContext(object obj)
{
_commandsManager.SetContext(obj);
}
///
/// Sets the context for the CommandsManager by GUID
///
///
public static void SetContext(Guid guid)
{
_commandsManager.SetContext(guid);
}
///
/// Sets the context for the CommandsManager by GUID string
///
///
public static void SetContext(string guidString)
{
_commandsManager.SetContext(guidString);
}
// == Built-in commands == //
///
/// Quit the Cogwheel console
///
[Command(Name = "quit", Description = "Quits the Cogwheel console.")]
public static void QuitCogwheelConsole()
{
_console.Exit();
}
///
/// Clears the console
///
[Command(Name = "clear", Description = "Clears the console.")]
public static void ClearConsole()
{
_console.ClearConsole();
}
///
/// Shows the description and usage of a given command
///
///
[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)}");
}
///
/// Lists all available commands
///
[Command(Name = "list", Description = "Lists all available commands.")]
public static void ListCommands()
{
foreach (var command in _commandsManager.Commands)
{
Write($"{_commandsManager.GetCommandUsage(command.Value)}");
}
}
///
/// Logs the current context type and GUID
///
[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}");
}
///
/// Adds an assembly to the CommandsManager for command discovery
///
///
public static void AddAssembly(Assembly assembly)
{
_commandsManager.AddAssembly(assembly);
}
///
/// Removes an assembly from the CommandsManager
///
///
public static void RemoveAssembly(Assembly assembly)
{
_commandsManager.RemoveAssembly(assembly);
}
///
/// Adds a custom parser for a given type
///
///
///
public static void AddCustomParser(Type type, Func parser)
{
_commandsManager.AddCustomParser(type, parser);
}
///
/// Logs all registered objects and their GUIDs, optionally filtered by type
///
///
[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}");
}
}
///
/// Sets the context to the specified registered object by GUID
///
///
[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}");
}
///
/// Initializes custom parsers for the Cogwheel system
///
///
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);
});
}
}