Add command system

This commit is contained in:
Stone_Red
2024-01-31 22:32:31 +01:00
parent 56bd9ec6a6
commit e7940d5c4c
10 changed files with 184 additions and 32 deletions
+15
View File
@@ -0,0 +1,15 @@
using TextLore.Models;
namespace TextLore.Commands;
public class TestCommand : Command
{
public override string Name => "test";
public override string Description => "A test command.";
public override Task<bool> Execute(ConsoleOutput consoleOutput, string[] args)
{
consoleOutput.WriteLine("This is a test command.");
return Task.FromResult(true);
}
}
+3 -3
View File
@@ -9,12 +9,12 @@
<link rel="stylesheet" href="app.css" /> <link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="console.css" /> <link rel="stylesheet" href="console.css" />
<link rel="stylesheet" href="TextLore.styles.css" /> <link rel="stylesheet" href="TextLore.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" /> <link rel="icon" type="image/png" href="favicon.ico" />
<HeadOutlet /> <HeadOutlet @rendermode="InteractiveServer" />
</head> </head>
<body> <body>
<Routes /> <Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script> <script src="_framework/blazor.web.js"></script>
</body> </body>
-1
View File
@@ -1,5 +1,4 @@
@page "/counter" @page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle> <PageTitle>Counter</PageTitle>
+8 -1
View File
@@ -1,5 +1,12 @@
@page "/" @page "/"
@using TextLore.Commands
@using TextLore.Models
<PageTitle>Home</PageTitle> <PageTitle>Home</PageTitle>
<TextLore.Components.Shared.Console /> <TextLore.Components.Shared.Console Commands="commands" />
@code
{
Command[] commands = [new TestCommand()];
}
+81 -24
View File
@@ -1,8 +1,6 @@
@using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Forms
@using TextLore.Models @using TextLore.Models
@rendermode InteractiveServer
<div id="console"> <div id="console">
<div id="header"> <div id="header">
<h4>@Name</h4> <h4>@Name</h4>
@@ -10,46 +8,105 @@
{ {
<h5> @DateTime.UtcNow.ToLongDateString()</h5> <h5> @DateTime.UtcNow.ToLongDateString()</h5>
} }
@if (!string.IsNullOrWhiteSpace(Description))
{
<h6>> @Description</h6> <h6>> @Description</h6>
}
</div> </div>
<div id="container"> <div id="container">
<EditForm OnValidSubmit="Execute" OnInvalidSubmit="Execute" autocomplete="off" Model="ConsoleInput" novalidate> <EditForm OnSubmit="Execute" autocomplete="off" Model="ConsoleInput" novalidate>
<div id="input-line" class="input-line"> <div id="input-line" class="input-line">
<div class="prompt"> <div class="prompt">
Command > Command >
</div> </div>
<div> <div>
<InputText id="commandline" autocomplete="off" class="cmdline" disabled="@Disabled" placeholder="@Placeholder" @bind-Value="@ConsoleInput.Text" /> <InputText @ref="inputText" id="commandline" autocomplete="off" class="cmdline" disabled="@disabled" placeholder="@Placeholder" @bind-Value="@ConsoleInput.Text" />
</div> </div>
</div> </div>
</EditForm> </EditForm>
<pre> <pre>
<code>@((MarkupString)Running)</code> <code>@((MarkupString)running)</code>
<code>@((MarkupString)Output)</code> <code>@((MarkupString)output)</code>
</pre> </pre>
</div> </div>
</div> </div>
@code { @code {
public string Output { get; set; } = "";
public string Running { get; set; } = "";
public string Name { get; set; } = "Main Menu";
public string Description { get; set; } = "Select a game mode";
public bool ShowDate { get; set; } = true;
public bool Disabled { get; set; } = false;
public string Placeholder { get; set; } = "Enter a command, type 'help' for avaliable commands.";
public ConsoleInput ConsoleInput { get; set; } = new ConsoleInput();
public void Execute(EditContext context) [Parameter, EditorRequired]
public string Name { get; set; } = "Console";
[Parameter]
public string? Description { get; set; }
[Parameter]
public bool ShowDate { get; set; } = true;
public string Placeholder => $"Enter a command{(HelpCommand is null ? "." : ", type 'help' for avaliable commands.")}";
public ConsoleInput ConsoleInput { get; set; } = new();
public ConsoleOutput ConsoleOutput { get; set; } = new();
[Parameter, EditorRequired]
public IEnumerable<Command> Commands { get; set; } = [];
[Parameter]
public Command? HelpCommand { get; set; }
private string output { get; set; } = "";
private string running { get; set; } = "";
private bool disabled { get; set; } = false;
private InputText? inputText;
protected override async Task OnAfterRenderAsync(bool firstRender)
{ {
Disabled = true; if (inputText?.Element is not null)
Running = ConsoleInput.Text; {
string newOutput = $"<p>"; await inputText.Element.Value.FocusAsync();
newOutput += $"<span class='header'>{DateTime.UtcNow.ToString("HH:mm")} > </span><span class='command'>{ConsoleInput.Text}{Environment.NewLine}</span>"; }
newOutput += $"1+1=3"; }
newOutput += $"</p>";
Output = newOutput + Output; protected override void OnInitialized()
ConsoleInput.Text = ""; {
Disabled = false; ConsoleOutput.OnOutput += WriteOutput;
}
public async Task Execute(EditContext context)
{
Command? command = Commands.FirstOrDefault(c=>c.Name.Equals(ConsoleInput.Text));
command ??= HelpCommand;
if(command is null)
{
running = $"[Failed] Command '{ConsoleInput.Text}' not found!";
ConsoleInput.Text = string.Empty;
return;
}
disabled = true;
running = $"<p>";
running += $"<span class='header'>{ConsoleInput.Time.ToString("HH:mm")} > </span><span class='command'>{ConsoleInput.Text}{Environment.NewLine}</span>";
bool success = await command.Execute(ConsoleOutput, []);
running += "</p>";
output = running + output;
running = success ? $"[Success]" : $"[Failed]";
ConsoleInput.Text = string.Empty;
disabled = false;
StateHasChanged();
}
public void WriteOutput(object? sender, ConsoleOutputEventArgs e)
{
string newOutput = e.Message;
output = newOutput + output;
StateHasChanged();
} }
} }
+11
View File
@@ -0,0 +1,11 @@
namespace TextLore.Models;
public abstract class Command
{
public abstract string Name { get; }
public abstract string Description { get; }
public virtual string Usage { get; } = string.Empty;
public virtual string[] Aliases { get; } = [];
public abstract Task<bool> Execute(ConsoleOutput consoleOutput, string[] args);
}
+9
View File
@@ -0,0 +1,9 @@
namespace TextLore.Models;
public enum ConsoleMessageType
{
Default,
Info,
Warning,
Error
}
+46
View File
@@ -0,0 +1,46 @@
namespace TextLore.Models;
public class ConsoleOutput
{
public event EventHandler<ConsoleOutputEventArgs>? OnOutput;
public void Write(string message, ConsoleMessageType consoleMessageType = ConsoleMessageType.Default)
{
OnOutput?.Invoke(this, new(message, consoleMessageType));
}
public void WriteLine(string message)
{
Write(message + Environment.NewLine);
}
public void WriteError(string message)
{
Write($"[ERROR] {message}", ConsoleMessageType.Error);
}
public void WriteErrorLine(string message)
{
WriteError(message + Environment.NewLine);
}
public void WriteWarning(string message)
{
Write($"[WARNING] {message}", ConsoleMessageType.Warning);
}
public void WriteWarningLine(string message)
{
WriteWarning(message + Environment.NewLine);
}
public void WriteInfo(string message)
{
Write($"[INFO] {message}", ConsoleMessageType.Info);
}
public void WriteInfoLine(string message)
{
WriteInfo(message + Environment.NewLine);
}
}
@@ -0,0 +1,8 @@
namespace TextLore.Models;
public class ConsoleOutputEventArgs(string message, ConsoleMessageType messageType) : EventArgs
{
public string Message { get; } = message;
public ConsoleMessageType MessageType { get; } = messageType;
}
+2 -2
View File
@@ -2,7 +2,7 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
margin: 0; margin: 0;
font-size: 11pt; font-size: 13pt;
font-family: monospace; font-family: monospace;
color: white; color: white;
background-color: black; background-color: black;
@@ -36,7 +36,7 @@
#console #container p { #console #container p {
margin: 0px; margin: 0px;
margin-bottom: 10px; margin-top: 10px;
} }
#console #container .prgs { #console #container .prgs {