using System; using System.Collections.Generic; using System.Reflection; using System.Runtime.CompilerServices; using FlaxEngine; using FlaxEngine.Assertions; namespace Game; [Flags] public enum ConsoleFlags { /// /// Value does not persist. /// NoSerialize = 1, } internal class ConsoleVariable { public string Name { get; } private readonly List _fields; private readonly List _getters; private readonly List _setters; public ConsoleVariable(string name) { Name = name; _fields = new List(); _getters = new List(); _setters = new List(); } public void AddField(FieldInfo field) { 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 Unsafe.As(field.GetValue(null)); if (getter != null) return Unsafe.As(getter.Invoke(null, null)); } else if (type == typeof(float)) { if (field != null) return field.GetValue(null).ToString(); if (getter != null) return getter.Invoke(null, null).ToString(); } else throw new Exception($"ConsoleVariable: Unsupported variable type '{type.FullName}'"); throw new Exception("ConsoleVariable: GetValueString no field or getter found"); } public void SetValue(string value) { foreach (var field in _fields) { Type type = field.FieldType; if (type == typeof(string)) field.SetValue(null, value); else if (type == typeof(float)) { if (!float.TryParse(value, out var floatValue)) return; field.SetValue(null, floatValue); } else throw new Exception($"ConsoleVariable: Unsupported type for SetValue: '{type.FullName}'"); } foreach (var setter in _setters) { 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}'"); } } }