Compare commits

..

No commits in common. "22b25cd8a85a982fb4de157ea93d730eaef4def3" and "83bc55526a228787247b44101582303fc6265af6" have entirely different histories.

7 changed files with 86 additions and 76 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>

View File

@ -8,15 +8,15 @@ public class DeafultCogwheelConsole : ICogwheelConsole
{ {
public string OpeningMessage { get; set; } = "** COGWHEEL CONSOLE **"; public string OpeningMessage { get; set; } = "** COGWHEEL CONSOLE **";
public bool IsRunning { get; set; } public bool IsRunning { get; set; }
public CommandsManager CommandsManager { get; set; } public ICommandsManager CommandsManager { get; set; }
public void Initialize(CommandsManager commandsManager) public void Initialize(ICommandsManager commandsManager)
{ {
CommandsManager = commandsManager; CommandsManager = commandsManager;
CommandsManager.RegisterObject(this); CommandsManager.RegisterObject(this);
Write(OpeningMessage); Log(OpeningMessage);
IsRunning = true; IsRunning = true;
while (IsRunning) while (IsRunning)
@ -42,11 +42,6 @@ public class DeafultCogwheelConsole : ICogwheelConsole
Console.WriteLine($"[COGWHEEL WARNING] {message}"); Console.WriteLine($"[COGWHEEL WARNING] {message}");
} }
public void Write(string message)
{
Console.WriteLine(message);
}
public void ClearConsole() public void ClearConsole()
{ {
Console.Clear(); Console.Clear();

View File

@ -3,7 +3,7 @@
using Cogwheel; using Cogwheel;
ICogwheelConsole cogwheelConsole = new DeafultCogwheelConsole(); ICogwheelConsole cogwheelConsole = new DeafultCogwheelConsole();
CommandsManager commandsManager = new CommandsManager(); ICommandsManager commandsManager = new CommandsManager(cogwheelConsole);
COGWHEEL.Initialize(commandsManager, cogwheelConsole); COGWHEEL.Initialize(commandsManager, cogwheelConsole);

View File

@ -2,15 +2,23 @@ namespace Cogwheel;
public static class COGWHEEL public static class COGWHEEL
{ {
private static CommandsManager _commandsManager; /* TODO:
* -[X] Initialize the CommandsManager
* -[ ] Public static methods for the CommandsManager
* -[X] Create built-in commands
* -[ ]
* -[ ]
* -[ ]
*/
private static ICommandsManager _commandsManager;
private static ICogwheelConsole _console; private static ICogwheelConsole _console;
public static void Initialize(CommandsManager commandsManager, ICogwheelConsole console) public static void Initialize(ICommandsManager commandsManager, ICogwheelConsole console)
{ {
_console = console;
_commandsManager = commandsManager; _commandsManager = commandsManager;
_console = console;
_commandsManager.Initialize(_console);
_console.Initialize(_commandsManager); _console.Initialize(_commandsManager);
} }
@ -43,11 +51,6 @@ public static class COGWHEEL
_console.LogWarning(message); _console.LogWarning(message);
} }
public static void Write(string message)
{
_console.Write(message);
}
// == Built-in commands == // // == Built-in commands == //
[Command(Name = "quit", Description = "Quits the Cogwheel console.")] [Command(Name = "quit", Description = "Quits the Cogwheel console.")]
public static void QuitCogwheelConsole() public static void QuitCogwheelConsole()
@ -81,7 +84,7 @@ public static class COGWHEEL
{ {
foreach (var command in _commandsManager.Commands) foreach (var command in _commandsManager.Commands)
{ {
Write($"{_commandsManager.GetCommandUsage(command.Value)}"); _console.Log($"{command.Key} - {command.Value.Description}");
} }
} }
@ -91,7 +94,7 @@ public static class COGWHEEL
_console.Log($"Current context: {_commandsManager.CurrentContext.GetType()} : {_commandsManager.CurrentContextGuid}"); _console.Log($"Current context: {_commandsManager.CurrentContext.GetType()} : {_commandsManager.CurrentContextGuid}");
} }
[Command(Name = "test", Description = "Creates a new TestClass object.")] [Command(Name = "test")]
public static void CreateTestObject(string name) public static void CreateTestObject(string name)
{ {
_console.Log($"Creating new TestClass object with name: {name}"); _console.Log($"Creating new TestClass object with name: {name}");
@ -115,7 +118,7 @@ public static class COGWHEEL
Log("Available registered objects:"); Log("Available registered objects:");
foreach (var (guid, obj) in filteredObjects) foreach (var (guid, obj) in filteredObjects)
{ {
Write($"- {obj.GetType().FullName} : {guid}"); Log($"- {obj.GetType().FullName} : {guid}");
} }
} }

View File

@ -6,30 +6,32 @@ using Exception = System.Exception;
namespace Cogwheel; namespace Cogwheel;
public class CommandsManager public class CommandsManager : ICommandsManager
{ {
protected virtual ICogwheelConsole CogwheelConsole { get; set; } public ICogwheelConsole CogwheelConsole { get; set; }
protected virtual string CommandPattern { get; set; } = "(?<val>(\\([^\\)]+\\)))|\"(?<val>[^\"]+)\"|'(?<val>[^']+)'|(?<val>[^\\s]+)";
protected virtual List<Assembly> Assemblies { get; set; } = []; public string CommandPattern { get; set; } = "(?<val>(\\([^\\)]+\\)))|\"(?<val>[^\"]+)\"|'(?<val>[^']+)'|(?<val>[^\\s]+)";
public virtual Dictionary<string, ICommand> Commands { get; set; } = new(); public List<Assembly> Assemblies { get; set; } = [];
public virtual Dictionary<Type, Func<string, object>> CustomParsers { get; set; } = new(); public Dictionary<string, ICommand> Commands { get; set; } = new();
public Dictionary<Type, Func<string, object>> CustomParsers { get; set; } = new();
// Context related stuff // Context related stuff
public virtual object? CurrentContext { get; set; } public object? CurrentContext { get; set; }
public virtual Guid? CurrentContextGuid { get; set; } public Guid? CurrentContextGuid { get; set; }
public virtual Dictionary<Guid, object> RegisteredObjectInstances { get; set; } = new(); public Dictionary<Guid, object> RegisteredObjectInstances { get; set; } = new();
public virtual Dictionary<object, Guid> RegisteredObjectGuids { get; set; } = new(); public Dictionary<object, Guid> RegisteredObjectGuids { get; set; } = new();
public virtual void Initialize(ICogwheelConsole console)
public CommandsManager(ICogwheelConsole console)
{ {
CogwheelConsole = console; CogwheelConsole = console;
RefreshCommandsList(); RefreshCommandsList();
CogwheelConsole.Log($"CommandsManager initialized, Commands found: {Commands.Count}"); CogwheelConsole.Log($"CommandsManager initialized, Commands found: {Commands.Count}");
} }
public virtual (ICommand, List<object>)? GetCommandAndArgsFromString(string input) public (ICommand, List<object>)? GetCommandAndArgsFromString(string input)
{ {
var splitString = Regex.Matches(input, CommandPattern).Select(m => m.Groups["val"].Value).ToArray(); var splitString = Regex.Matches(input, CommandPattern).Select(m => m.Groups["val"].Value).ToArray();
var commandName = splitString[0]; var commandName = splitString[0];
@ -47,7 +49,7 @@ public class CommandsManager
return null; return null;
} }
public virtual bool RunCommand(string input, object? context = null) public bool RunCommand(string input, object? context = null)
{ {
if (string.IsNullOrWhiteSpace(input)) return false; if (string.IsNullOrWhiteSpace(input)) return false;
var command = GetCommandAndArgsFromString(input); var command = GetCommandAndArgsFromString(input);
@ -72,7 +74,7 @@ public class CommandsManager
return ExecuteCommand(CurrentContext, command.Value); return ExecuteCommand(CurrentContext, command.Value);
} }
//CogwheelConsole.LogWarning($"Command '{command.Value.Item1.Name}' is not static and no valid context was provided, searching for first registered context of type '{command.Value.Item1.Method.DeclaringType}'"); CogwheelConsole.LogWarning($"Command '{command.Value.Item1.Name}' is not static and no valid context was provided, searching for first registered context of type '{command.Value.Item1.Method.DeclaringType}'");
context = GetFirstValidRegisteredContext(command.Value.Item1.Method.DeclaringType); context = GetFirstValidRegisteredContext(command.Value.Item1.Method.DeclaringType);
if (context is null) if (context is null)
{ {
@ -88,38 +90,16 @@ public class CommandsManager
return false; return false;
} }
public virtual string GetCommandUsage(ICommand command) public string GetCommandUsage(ICommand command)
{ {
string output = "";
if (!command.Method.IsStatic)
{
output += $"|{command.Method.DeclaringType?.FullName}| ";
}
else
{
output += "|Global| ";
}
output += $"{command.Name}: ";
if (!string.IsNullOrWhiteSpace(command.Description))
{
output += $"{command.Description} ";
}
string paramUsage = string.Join(" ", string paramUsage = string.Join(" ",
command.Method.GetParameters().Select(param => command.Method.GetParameters().Select(param =>
$"<{(param.IsDefined(typeof(ParamArrayAttribute)) ? "params " : "")}{param}>")); $"<{(param.IsDefined(typeof(ParamArrayAttribute)) ? "params " : "")}{param}>"));
if (!string.IsNullOrWhiteSpace(paramUsage)) return $"{command.Name}: {paramUsage}";
{
output += $"- {paramUsage}";
}
return output;
} }
public virtual bool ExecuteCommand(object obj, (ICommand command, List<object> args) command) public bool ExecuteCommand(object obj, (ICommand command, List<object> args) command)
{ {
var parameters = command.command.Method.GetParameters(); var parameters = command.command.Method.GetParameters();
for (var parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++) for (var parameterIndex = 0; parameterIndex < parameters.Length; parameterIndex++)
@ -183,7 +163,7 @@ public class CommandsManager
} }
} }
public virtual bool TryParseParameter(Type parameterType, string parameterString, out object parsedValue) public bool TryParseParameter(Type parameterType, string parameterString, out object parsedValue)
{ {
if (parameterType == typeof(string)) if (parameterType == typeof(string))
{ {
@ -229,14 +209,14 @@ public class CommandsManager
return false; return false;
} }
public virtual ICommand? GetCommandByName(string commandName) public ICommand? GetCommandByName(string commandName)
{ {
return Commands.GetValueOrDefault(commandName); return Commands.GetValueOrDefault(commandName);
} }
// Context related stuff // Context related stuff
public virtual void RegisterObject(object obj) public void RegisterObject(object obj)
{ {
// Use a combination of the object's type and a hash of its properties to generate a deterministic GUID // Use a combination of the object's type and a hash of its properties to generate a deterministic GUID
string seed = obj.GetType().FullName + GetObjectPropertiesHash(obj); string seed = obj.GetType().FullName + GetObjectPropertiesHash(obj);
@ -258,7 +238,7 @@ public class CommandsManager
} }
} }
public virtual bool IsCommandContextValid(ICommand command, object? context = null) public bool IsCommandContextValid(ICommand command, object? context = null)
{ {
if (context is not null) if (context is not null)
{ {
@ -267,7 +247,7 @@ public class CommandsManager
return command.Method.DeclaringType == CurrentContext?.GetType(); return command.Method.DeclaringType == CurrentContext?.GetType();
} }
public virtual bool SetContext(object context) public bool SetContext(object context)
{ {
CurrentContext = context; CurrentContext = context;
if (!RegisteredObjectGuids.ContainsKey(context)) if (!RegisteredObjectGuids.ContainsKey(context))
@ -279,7 +259,7 @@ public class CommandsManager
return true; return true;
} }
public virtual bool SetContext(Guid guid) public bool SetContext(Guid guid)
{ {
if (RegisteredObjectInstances.ContainsKey(guid)) if (RegisteredObjectInstances.ContainsKey(guid))
{ {
@ -295,7 +275,7 @@ public class CommandsManager
return true; return true;
} }
public virtual bool SetContext(string guidString) public bool SetContext(string guidString)
{ {
if (Guid.TryParse(guidString, out var guid)) if (Guid.TryParse(guidString, out var guid))
{ {
@ -306,12 +286,12 @@ public class CommandsManager
return false; return false;
} }
public virtual object? GetFirstValidRegisteredContext(Type type) public object? GetFirstValidRegisteredContext(Type type)
{ {
return RegisteredObjectInstances.Values.FirstOrDefault(obj => obj.GetType() == type); return RegisteredObjectInstances.Values.FirstOrDefault(obj => obj.GetType() == type);
} }
public virtual Guid GetGuidFromContext(object? context = null) public Guid GetGuidFromContext(object? context = null)
{ {
if (context is not null) if (context is not null)
{ {
@ -321,7 +301,7 @@ public class CommandsManager
return CurrentContextGuid ?? Guid.Empty; return CurrentContextGuid ?? Guid.Empty;
} }
protected virtual string GetObjectPropertiesHash(object obj) private string GetObjectPropertiesHash(object obj)
{ {
var properties = obj.GetType().GetProperties(); var properties = obj.GetType().GetProperties();
var sb = new StringBuilder(); var sb = new StringBuilder();
@ -335,7 +315,7 @@ public class CommandsManager
return sb.ToString(); return sb.ToString();
} }
protected virtual void RefreshCommandsList() private void RefreshCommandsList()
{ {
foreach (var type in Assembly.GetCallingAssembly().GetTypes()) foreach (var type in Assembly.GetCallingAssembly().GetTypes())
{ {

View File

@ -4,13 +4,12 @@ public interface ICogwheelConsole
{ {
public string OpeningMessage { get; set; } public string OpeningMessage { get; set; }
public bool IsRunning { get; set; } public bool IsRunning { get; set; }
public CommandsManager CommandsManager { get; set; } public ICommandsManager CommandsManager { get; set; }
public void Initialize(CommandsManager commandsManager); // Make sure to pass the CommandsManager instance to the Console public void Initialize(ICommandsManager commandsManager); // Make sure to pass the CommandsManager instance to the Console
public void Log(string message); public void Log(string message);
public void LogError(string message); public void LogError(string message);
public void LogWarning(string message); public void LogWarning(string message);
public void Write(string message);
public void ClearConsole(); public void ClearConsole();
public void Exit(); public void Exit();

View File

@ -0,0 +1,33 @@
using System.Reflection;
namespace Cogwheel;
public interface ICommandsManager
{
public ICogwheelConsole CogwheelConsole { get; set; }
public string CommandPattern { get; set; }
public List<Assembly> Assemblies { get; set; }
public Dictionary<string, ICommand> Commands { get; set; }
public Dictionary<Type, Func<string, object>> CustomParsers { get; set; }
public object? CurrentContext { get; set; }
public Guid? CurrentContextGuid { get; set; }
public Dictionary<Guid, object> RegisteredObjectInstances { get; set; }
public Dictionary<object, Guid> RegisteredObjectGuids { get; set; }
public void RegisterObject(object obj);
public (ICommand, List<object>)? GetCommandAndArgsFromString(string input);
public bool RunCommand(string input, object? context = null);
public string GetCommandUsage(ICommand command);
public bool ExecuteCommand(object obj, (ICommand command, List<object> args) command);
public bool TryParseParameter(Type parameterType, string parameterString, out object parsedValue);
public ICommand? GetCommandByName(string commandName);
// Context related stuff
public bool IsCommandContextValid(ICommand command, object? context = null);
public bool SetContext(object context);
public bool SetContext(Guid guid);
public bool SetContext(string guidString);
public object? GetFirstValidRegisteredContext(Type type);
public Guid GetGuidFromContext(object? context = null);
}