first
This commit is contained in:
169
Runtime/Engine/Code/Services/Console/CVar.cs
Normal file
169
Runtime/Engine/Code/Services/Console/CVar.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using System;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
public enum CVarValueKind {
|
||||
Number, String
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct CVarValue {
|
||||
public CVarValueKind Kind;
|
||||
|
||||
public double NumberValue;
|
||||
public string StringValue;
|
||||
|
||||
public CVarValue(int value) {
|
||||
Kind = CVarValueKind.Number;
|
||||
NumberValue = value;
|
||||
StringValue = null;
|
||||
}
|
||||
|
||||
public CVarValue(float value) {
|
||||
Kind = CVarValueKind.Number;
|
||||
NumberValue = value;
|
||||
StringValue = null;
|
||||
}
|
||||
|
||||
public CVarValue(double value) {
|
||||
Kind = CVarValueKind.Number;
|
||||
NumberValue = value;
|
||||
StringValue = null;
|
||||
}
|
||||
|
||||
public CVarValue(string value) {
|
||||
Kind = CVarValueKind.String;
|
||||
NumberValue = 0;
|
||||
StringValue = value;
|
||||
}
|
||||
|
||||
public void CopyFrom(CVarValue value) {
|
||||
Kind = value.Kind;
|
||||
NumberValue = value.NumberValue;
|
||||
StringValue = value.StringValue;
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return Kind switch {
|
||||
CVarValueKind.Number => NumberValue.ToString(),
|
||||
CVarValueKind.String => $"\"{StringValue}\"",
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum CVarFlags {
|
||||
None, Persistent, ReadOnly
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class CVar {
|
||||
public CVarFlags Flags;
|
||||
public string Name;
|
||||
public string Description;
|
||||
public CVarValue DefaultValue;
|
||||
public CVarValue Value { get; private set; }
|
||||
|
||||
public int IndexValue => (int) Value.NumberValue;
|
||||
public float FloatValue => (float) Value.NumberValue;
|
||||
public double NumberValue => Value.NumberValue;
|
||||
public string StringValue => Value.StringValue;
|
||||
|
||||
public event Action OnChanged = delegate { };
|
||||
|
||||
public CVar(CVar other) {
|
||||
Flags = other.Flags;
|
||||
Name = other.Name;
|
||||
Description = other.Description;
|
||||
DefaultValue = other.DefaultValue;
|
||||
Value = other.Value;
|
||||
}
|
||||
|
||||
public CVar(string name, CVarValue value, string description = "") {
|
||||
Name = name;
|
||||
Description = description;
|
||||
DefaultValue = value;
|
||||
Value = DefaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, int value, string description = "") {
|
||||
Name = name;
|
||||
Description = description;
|
||||
DefaultValue = new CVarValue(value);
|
||||
Value = DefaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, float value, string description = "") {
|
||||
Name = name;
|
||||
Description = description;
|
||||
DefaultValue = new CVarValue(value);
|
||||
Value = DefaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, double value, string description = "") {
|
||||
Name = name;
|
||||
Description = description;
|
||||
DefaultValue = new CVarValue(value);
|
||||
Value = DefaultValue;
|
||||
}
|
||||
|
||||
public CVar(string name, string value, string description = "") {
|
||||
Name = name;
|
||||
Description = description;
|
||||
DefaultValue = new CVarValue(value);
|
||||
Value = DefaultValue;
|
||||
}
|
||||
|
||||
public void Set(int value) {
|
||||
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = new CVarValue(value);
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void Set(float value) {
|
||||
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = new CVarValue(value);
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void Set(string value) {
|
||||
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = new CVarValue(value);
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void ParseFromString(string str) {
|
||||
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (float.TryParse(str, out float f)) {
|
||||
Set(f);
|
||||
} else {
|
||||
Set(str);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
if (Flags.HasFlag(CVarFlags.ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Value = DefaultValue;
|
||||
OnChanged?.Invoke();
|
||||
}
|
||||
|
||||
public override string ToString() {
|
||||
return Value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Services/Console/CVar.cs.meta
Normal file
3
Runtime/Engine/Code/Services/Console/CVar.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f560b25a893456c90fac62ad278c02b
|
||||
timeCreated: 1740779755
|
||||
19
Runtime/Engine/Code/Services/Console/CVarAsset.cs
Normal file
19
Runtime/Engine/Code/Services/Console/CVarAsset.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
[CreateAssetMenu(fileName = RConsts.AssetMenu + "cvar")]
|
||||
public class CVarAsset : ScriptableObject {
|
||||
[SerializeField]
|
||||
private CVar _cvar;
|
||||
|
||||
public CVar Create(string name = null) {
|
||||
CVar cvar = new CVar(_cvar);
|
||||
|
||||
if (name != null) {
|
||||
cvar.Name = name;
|
||||
}
|
||||
|
||||
return cvar;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Services/Console/CVarAsset.cs.meta
Normal file
3
Runtime/Engine/Code/Services/Console/CVarAsset.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 443a66c3a441450d96d222872a567df0
|
||||
timeCreated: 1741639598
|
||||
193
Runtime/Engine/Code/Services/Console/ConsoleService.cs
Normal file
193
Runtime/Engine/Code/Services/Console/ConsoleService.cs
Normal file
@@ -0,0 +1,193 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using RebootKit.Engine.Foundation;
|
||||
using RebootKit.Engine.Services.Input;
|
||||
using UnityEngine.InputSystem;
|
||||
using Logger = RebootKit.Engine.Foundation.Logger;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
public interface IConsoleCommand {
|
||||
string Name { get; }
|
||||
string Description { get; }
|
||||
void Execute(string[] args);
|
||||
}
|
||||
|
||||
public class HelpCommand : IConsoleCommand {
|
||||
public string Name { get; } = "help";
|
||||
public string Description { get; } = "Prints available commands/cvars and their descriptions.";
|
||||
|
||||
public void Execute(string[] args) {
|
||||
RR.Console().PrintHelp();
|
||||
}
|
||||
}
|
||||
|
||||
public class ConsoleService : IService {
|
||||
private static readonly Logger _logger = new(nameof(ConsoleService));
|
||||
|
||||
[Serializable]
|
||||
public class Config {
|
||||
public ConsoleUI ConsoleUIPrefab;
|
||||
public ScriptableInputAction ToggleAction;
|
||||
}
|
||||
|
||||
private ConsoleUI _ui;
|
||||
private Config _config;
|
||||
|
||||
private List<IConsoleCommand> _commands = new();
|
||||
private List<CVar> _cvars = new();
|
||||
|
||||
public bool IsVisible => _ui.IsVisible;
|
||||
|
||||
public ConsoleService(Config config) {
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public async UniTask OnInit(CancellationToken cancellationToken) {
|
||||
_logger.Info("Waking up");
|
||||
|
||||
_ui = UnityEngine.Object.Instantiate(_config.ConsoleUIPrefab);
|
||||
UnityEngine.Object.DontDestroyOnLoad(_ui.gameObject);
|
||||
await UniTask.Yield(cancellationToken);
|
||||
|
||||
_config.ToggleAction.Action.Enable();
|
||||
_config.ToggleAction.Action.performed += OnToggleAction;
|
||||
|
||||
RegisterCommand(new HelpCommand());
|
||||
|
||||
_ui.SetVisibility(false);
|
||||
_ui.Clear();
|
||||
_ui.Write("Hello shelf\n");
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
if (_ui != null) {
|
||||
UnityEngine.Object.Destroy(_ui);
|
||||
_ui = null;
|
||||
}
|
||||
|
||||
_config.ToggleAction.Action.performed -= OnToggleAction;
|
||||
}
|
||||
|
||||
public CVar GetCVar(string name) {
|
||||
foreach (CVar cvar in _cvars) {
|
||||
if (cvar.Name.Equals(name)) {
|
||||
return cvar;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public CVar ReplaceOrDefault(CVar cvar) {
|
||||
CVar foundCVar = GetCVar(cvar.Name);
|
||||
if (foundCVar != null) {
|
||||
return foundCVar;
|
||||
}
|
||||
|
||||
_cvars.Add(cvar);
|
||||
return cvar;
|
||||
}
|
||||
|
||||
public void Replace(CVar cvar) {
|
||||
CVar foundCVar = GetCVar(cvar.Name);
|
||||
if (foundCVar != null) {
|
||||
_cvars.Remove(foundCVar);
|
||||
}
|
||||
|
||||
_cvars.Add(cvar);
|
||||
}
|
||||
|
||||
private string[] ParseCommandInputArguments(string text) {
|
||||
if (text.Length == 0) {
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
return new string[] {text};
|
||||
}
|
||||
|
||||
public void Execute(string input) {
|
||||
if (input.Length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
string commandName = input;
|
||||
if (input.IndexOf(' ') != -1) {
|
||||
commandName = input.Substring(0, input.IndexOf(' '));
|
||||
}
|
||||
|
||||
string[] arguments = ParseCommandInputArguments(input.Substring(commandName.Length));
|
||||
|
||||
foreach (IConsoleCommand command in _commands) {
|
||||
if (command.Name.Equals(commandName)) {
|
||||
command.Execute(arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
foreach (CVar cvar in _cvars) {
|
||||
if (cvar.Name.Equals(commandName)) {
|
||||
if (arguments.Length == 1) {
|
||||
cvar.ParseFromString(arguments[0]);
|
||||
}
|
||||
|
||||
_ui.Write($"<b>{cvar.Name}</b> - {cvar.ToString()}\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_ui.Write($"ERROR: Command/CVar `{commandName}` not found.");
|
||||
}
|
||||
|
||||
public void ToggleVisibility() {
|
||||
_ui.SetVisibility(!_ui.IsVisible);
|
||||
|
||||
if (_ui.IsVisible) {
|
||||
// RR.Input().DisableControls();
|
||||
} else {
|
||||
RR.Input().EnableControls();
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterCommand(IConsoleCommand command) {
|
||||
if (_commands.Any(t => t.Name.Equals(command.Name))) {
|
||||
_logger.Error($"`{command.Name}` command is already registered");
|
||||
return;
|
||||
}
|
||||
|
||||
_commands.Add(command);
|
||||
_logger.Info($"Registered command: {command.Name}");
|
||||
}
|
||||
|
||||
public void PrintHelp() {
|
||||
StringBuilder message = new();
|
||||
|
||||
message.AppendLine("Available commands:");
|
||||
foreach (IConsoleCommand command in _commands) {
|
||||
message.Append(" ");
|
||||
message.Append(command.Name);
|
||||
message.Append(" - ");
|
||||
message.Append(command.Description);
|
||||
message.AppendLine();
|
||||
}
|
||||
|
||||
message.AppendLine("Available cvars:");
|
||||
foreach (CVar cvar in _cvars) {
|
||||
message.Append(" ");
|
||||
message.Append(cvar.Name);
|
||||
message.Append(" - ");
|
||||
message.Append(cvar.Description);
|
||||
message.AppendLine();
|
||||
}
|
||||
|
||||
_ui.Write(message.ToString());
|
||||
}
|
||||
|
||||
private void OnToggleAction(InputAction.CallbackContext obj) {
|
||||
ToggleVisibility();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b841238f225048e88d8d8d89cfeafaa7
|
||||
timeCreated: 1740884588
|
||||
34
Runtime/Engine/Code/Services/Console/ConsoleServiceAsset.cs
Normal file
34
Runtime/Engine/Code/Services/Console/ConsoleServiceAsset.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using RebootKit.Engine.Foundation;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
[CreateAssetMenu(menuName = RConsts.ServiceAssetMenu + "Console")]
|
||||
public class ConsoleServiceAsset : ServiceAsset<ConsoleService> {
|
||||
[SerializeField]
|
||||
private ConsoleService.Config _config;
|
||||
|
||||
[SerializeField]
|
||||
private CVar[] _initialCVars;
|
||||
|
||||
[SerializeField]
|
||||
private bool _loadCVarsFromResources = true;
|
||||
|
||||
public override ConsoleService Create() {
|
||||
ConsoleService service = new(_config);
|
||||
foreach (CVar cvar in _initialCVars) {
|
||||
service.Replace(cvar);
|
||||
cvar.Reset();
|
||||
}
|
||||
|
||||
if (_loadCVarsFromResources) {
|
||||
CVarAsset[] cvarsAssets = Resources.LoadAll<CVarAsset>("cvar");
|
||||
foreach (CVarAsset cvarAsset in cvarsAssets) {
|
||||
CVar cvar = cvarAsset.Create();
|
||||
service.Replace(cvar);
|
||||
}
|
||||
}
|
||||
|
||||
return new ConsoleService(_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 577b018c25510774aaccba06137e264d
|
||||
52
Runtime/Engine/Code/Services/Console/ConsoleUI.cs
Normal file
52
Runtime/Engine/Code/Services/Console/ConsoleUI.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace RebootKit.Engine.Services.Console {
|
||||
public class ConsoleUI : MonoBehaviour {
|
||||
private StringBuilder _content = new();
|
||||
|
||||
[SerializeField]
|
||||
private UIDocument _document;
|
||||
|
||||
private TextField _textField;
|
||||
private Button _submitButton;
|
||||
|
||||
public bool IsVisible { get; private set; }
|
||||
|
||||
private void Awake() {
|
||||
|
||||
VisualElement root = _document.rootVisualElement;
|
||||
return;
|
||||
// _textField = root.Q<TextField>("console-text-field");
|
||||
// _submitButton = root.Q<Button>("console-btn-submit");
|
||||
// _submitButton.clicked += OnSubmitButtonClicked;
|
||||
}
|
||||
|
||||
private void OnSubmit(string input) {
|
||||
RR.Console().Execute(input);
|
||||
_textField.value = input;
|
||||
}
|
||||
|
||||
public void SetVisibility(bool visible) {
|
||||
_document.enabled = visible;
|
||||
}
|
||||
|
||||
public void Write(string message) {
|
||||
_content.Append(message);
|
||||
//_textField.value = _content.ToString();
|
||||
}
|
||||
|
||||
public void Clear() {
|
||||
_content.Clear();
|
||||
|
||||
if (_textField != null) {
|
||||
_textField.value = "";
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSubmitButtonClicked() {
|
||||
OnSubmit(_textField.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Runtime/Engine/Code/Services/Console/ConsoleUI.cs.meta
Normal file
3
Runtime/Engine/Code/Services/Console/ConsoleUI.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca844a0157054677b2f129fdbf6ddc45
|
||||
timeCreated: 1740780314
|
||||
Reference in New Issue
Block a user