cvar overhaul

This commit is contained in:
2025-03-20 23:29:47 +02:00
parent b5c79a8088
commit d68c1c26ff
6 changed files with 117 additions and 75 deletions

3
.gitignore vendored
View File

@@ -30,4 +30,5 @@ Assets/desktop.ini
Assets/Maps/autosave/
Demos/
console.log
console-1.log
console-1.log
Content/devconfig.cfg

View File

@@ -13,7 +13,7 @@ public class CameraMovement : Script
public float MoveSpeed { get; set; } = 400;
[ConsoleVariable("sensitivity")]
public static float Sensitivity;
private static float _sensitivity { get; set; } = 1.0f;
public override void OnStart()
{
@@ -29,8 +29,8 @@ public class CameraMovement : Script
Actor rootActor = Actor.GetChild(0);
Camera camera = rootActor.GetChild<Camera>();
float xAxis = Input.GetAxisRaw("Mouse X") * Sensitivity;
float yAxis = Input.GetAxisRaw("Mouse Y") * Sensitivity;
float xAxis = Input.GetAxisRaw("Mouse X") * _sensitivity;
float yAxis = Input.GetAxisRaw("Mouse Y") * _sensitivity;
if (xAxis != 0.0f || yAxis != 0.0f)
{
viewPitch += yAxis;

View File

@@ -148,7 +148,7 @@ public class ConsoleInstance : IDisposable
private readonly List<string> consoleBufferHistory = new();
private readonly Dictionary<string, ConsoleCommand> consoleCommands = new();
private readonly List<ConsoleLine> consoleLines = new();
private readonly Dictionary<string, ConsoleVariable> consoleVariables = new();
private readonly Dictionary<string, (ConsoleVariable cvar, bool alias)> consoleVariables = new();
private readonly Stopwatch closeThrottleStopwatch = Stopwatch.StartNew();
private StreamWriter logStream;
@@ -294,7 +294,7 @@ public class ConsoleInstance : IDisposable
consoleCommands.Add(kv.Key, cmd);
}
foreach (FieldInfo field in type.GetFields())
foreach (FieldInfo field in type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
{
if (!field.IsStatic)
continue;
@@ -306,36 +306,42 @@ public class ConsoleInstance : IDisposable
if (attr is ConsoleVariableAttribute cvarAttribute)
{
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
consoleVariables.Add(cvarAttribute.name,
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, field));
if (!consoleVariables.TryGetValue(cvarAttribute.name, out var entry))
{
entry.cvar = new ConsoleVariable(cvarAttribute.name);
consoleVariables.Add(cvarAttribute.name, entry);
}
entry.cvar.AddField(field);
foreach (string alias in cvarAttribute.aliases)
consoleVariables.Add(alias,
new ConsoleVariable(cvarAttribute.name,
cvarAttribute.flags | ConsoleFlags.NoSerialize, field));
consoleVariables.Add(alias, (entry.cvar, true));
}
}
}
foreach (PropertyInfo prop in type.GetProperties())
foreach (PropertyInfo property in type.GetProperties(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
{
MethodInfo getter = prop.GetGetMethod();
MethodInfo setter = prop.GetSetMethod();
if (getter == null || setter == null || !getter.IsStatic || !setter.IsStatic)
continue;
var attributes = Attribute.GetCustomAttributes(prop);
var attributes = Attribute.GetCustomAttributes(property);
foreach (Attribute attr in attributes)
{
if (attr is ConsoleVariableAttribute cvarAttribute)
{
MethodInfo getter = property.GetGetMethod() ?? property.GetMethod;
MethodInfo setter = property.GetSetMethod() ?? property.SetMethod;
if (getter == null || setter == null || !getter.IsStatic || !setter.IsStatic)
continue;
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
consoleVariables.Add(cvarAttribute.name,
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, getter, setter));
if (!consoleVariables.TryGetValue(cvarAttribute.name, out var entry))
{
entry.cvar = new ConsoleVariable(cvarAttribute.name);
consoleVariables.Add(cvarAttribute.name, entry);
}
entry.cvar.AddProperty(property);
foreach (string alias in cvarAttribute.aliases)
consoleVariables.Add(alias,
new ConsoleVariable(cvarAttribute.name,
cvarAttribute.flags | ConsoleFlags.NoSerialize, getter, setter));
consoleVariables.Add(alias, (entry.cvar, true));
}
}
}
@@ -479,13 +485,13 @@ public class ConsoleInstance : IDisposable
cmd.Invoke();
//Console.Print("Command bound to '" + execute + "' is '" + cmd.method.Name + "'");
}
else if (consoleVariables.TryGetValue(executeLower, out ConsoleVariable cvar))
else if (consoleVariables.TryGetValue(executeLower, out var entry))
{
if (value != null)
cvar.SetValue(value);
entry.cvar.SetValue(value);
if (!noOutput)
Console.Print("'" + execute + "' is '" + cvar.GetValueString() + "'");
Console.Print("'" + execute + "' is '" + entry.cvar.GetValueString() + "'");
}
else
{
@@ -503,9 +509,9 @@ public class ConsoleInstance : IDisposable
public string GetVariable(string variableName)
{
if (consoleVariables.TryGetValue(variableName, out ConsoleVariable cvar))
if (consoleVariables.TryGetValue(variableName, out var entry))
{
string value = cvar.GetValueString();
string value = entry.cvar.GetValueString();
return value;
}

View File

@@ -38,7 +38,7 @@ public class ConsoleVariableAttribute : ConsoleBaseAttribute
public class ConsoleCommandAttribute : ConsoleBaseAttribute
{
/// <summary>
/// Registers a command to Console system.
/// Registers a command to Console system.
/// </summary>
/// <param name="name">Name used for calling this command.</param>
public ConsoleCommandAttribute(string name) : base(name)
@@ -46,11 +46,11 @@ public class ConsoleCommandAttribute : ConsoleBaseAttribute
}
/// <summary>
/// Registers a command to Console system.
/// Registers a command to Console system.
/// </summary>
/// <param name="names">
/// Names used for calling this command. First name is the main name for this command, rest of the
/// names are aliases.
/// Names used for calling this command. First name is the main name for this command,
/// rest of the names are aliases.
/// </param>
public ConsoleCommandAttribute(params string[] names) : base(names)
{
@@ -58,7 +58,7 @@ public class ConsoleCommandAttribute : ConsoleBaseAttribute
}
/// <summary>
/// Constructor for the subsystem, must be called first before registering console commands.
/// Constructor for the subsystem, must be called first before registering console commands.
/// </summary>
[AttributeUsage(AttributeTargets.All)]
public class ConsoleSubsystemInitializer : Attribute

View File

@@ -1,88 +1,123 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using FlaxEngine;
using FlaxEngine.Assertions;
namespace Game;
[Flags]
public enum ConsoleFlags
{
NoSerialize = 1, // Value does not persist
Alias = NoSerialize
/// <summary>
/// Value does not persist.
/// </summary>
NoSerialize = 1,
}
internal struct ConsoleVariable
internal class ConsoleVariable
{
public string name { get; }
public ConsoleFlags flags { get; }
public string Name { get; }
private readonly FieldInfo field;
private readonly MethodInfo getter;
private readonly MethodInfo setter;
private readonly List<FieldInfo> _fields;
private readonly List<MethodInfo> _getters;
private readonly List<MethodInfo> _setters;
public ConsoleVariable(string name, ConsoleFlags flags, FieldInfo field)
public ConsoleVariable(string name)
{
this.name = name;
this.flags = flags;
this.field = field;
getter = null;
setter = null;
Name = name;
_fields = new List<FieldInfo>();
_getters = new List<MethodInfo>();
_setters = new List<MethodInfo>();
}
public ConsoleVariable(string name, ConsoleFlags flags, MethodInfo getter, MethodInfo setter)
public void AddField(FieldInfo field)
{
this.name = name;
this.flags = flags;
field = null;
this.getter = getter;
this.setter = setter;
Assert.IsTrue(_getters.Count == 0);
_fields.Add(field);
}
public void AddProperty(PropertyInfo property)
{
var getter = property.GetGetMethod() ?? property.GetMethod;
var setter = property.GetSetMethod() ?? property.SetMethod;
Assert.IsNotNull(getter);
Assert.IsNotNull(setter);
if (getter != null)
_getters.Add(getter);
if (setter != null)
_setters.Add(setter);
//Assert.IsTrue(_getters.Count > 0);
//Assert.IsTrue(_setters.Count <= 1);
/*if (setter == null)
{
FieldInfo backingField = property.DeclaringType.GetField($"<{property.Name}>k__BackingField", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (backingField != null)
_fields.Add(backingField);
}*/
}
public string GetValueString()
{
FieldInfo field = _fields.Count > 0 ? _fields[0] : null;
MethodInfo getter = _getters.Count > 0 ? _getters[0] : null;
Type type = field != null ? field.FieldType : getter.ReturnType;
if (type == typeof(string))
{
if (field != null)
return (string)field.GetValue(null);
if (getter != null)
return (string)getter.Invoke(null, null);
return ((float)getter.Invoke(null, null)).ToString();
}
else if (type == typeof(float))
{
if (field != null)
return field.GetValue(null).ToString();
if (getter != null)
return (string)getter.Invoke(null, null);
return ((float)getter.Invoke(null, null)).ToString();
}
else
throw new Exception($"Unsupported console variable type '{type.FullName}'");
throw new Exception($"ConsoleVariable: Unsupported variable type '{type.FullName}'");
throw new Exception("GetValueString no field or getter specified");
throw new Exception("ConsoleVariable: GetValueString no field or getter found");
}
public void SetValue(string value)
{
Type type = field != null ? field.FieldType : getter.ReturnType;
if (type == typeof(string))
foreach (var field in _fields)
{
if (field != null)
Type type = field.FieldType;
if (type == typeof(string))
field.SetValue(null, value);
else if (setter != null)
setter.Invoke(null, new object[] { value });
}
else if (type == typeof(float))
{
if (!float.TryParse(value, out var floatValue))
return;
if (field != null)
else if (type == typeof(float))
{
if (!float.TryParse(value, out var floatValue))
return;
field.SetValue(null, floatValue);
else if (setter != null)
setter.Invoke(null, new object[] { floatValue });
}
else
throw new Exception($"ConsoleVariable: Unsupported type for SetValue: '{type.FullName}'");
}
else
foreach (var setter in _setters)
{
throw new Exception("Unsupported type for SetValue: " + type.Name);
Type type = setter.GetParameterTypes()[0];
if (type == typeof(string))
setter.Invoke(null, new object[] { value });
else if (type == typeof(float))
{
if (!float.TryParse(value, out var floatValue))
return;
setter.Invoke(null, new object[] { floatValue });
}
else
throw new Exception($"ConsoleVariable: Unsupported type for SetValue: '{type.FullName}'");
}
}
}

View File

@@ -51,7 +51,7 @@ public class PlayerInput2 : IPlayerInput
private PlayerInputState2 _recordState;
[ConsoleVariable("sensitivity")]
public static float Sensitivity;
private static float _sensitivity { get; set; } = 1.0f;
public void SetFrame(ulong frame)
{
@@ -67,7 +67,7 @@ public class PlayerInput2 : IPlayerInput
//sensitivity = 1.0f;
float turnSpeed = 100.0f;
_recordState.ViewDelta += new Float2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * Sensitivity;
_recordState.ViewDelta += new Float2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y")) * _sensitivity;
_recordState.ViewDelta += new Float2(Input.GetAxisRaw("LookRight"), Input.GetAxisRaw("LookUp")) * Time.DeltaTime * turnSpeed;
_recordState.MoveForward = MathF.MaxMagnitude(_recordState.MoveForward, Input.GetAxis("Vertical"));