mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Scripts: First implementation of Range- and Readonly-Attributes + added support for all primitive types
This commit is contained in:
@@ -6,6 +6,8 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
|
using GlitchyEngine.Extensions;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
namespace GlitchyEngine.Editor;
|
namespace GlitchyEngine.Editor;
|
||||||
@@ -38,8 +40,17 @@ internal class EntityEditor
|
|||||||
ShowEditor(entityType, instance);
|
ShowEditor(entityType, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static object ShowFieldEditor(object reference, Type fieldType, string fieldName)
|
public static object ShowFieldEditor(object reference, Type fieldType, string fieldName, IEnumerable<Attribute> attributes = null)
|
||||||
{
|
{
|
||||||
|
T GetAttribute<T>() where T : Attribute
|
||||||
|
{
|
||||||
|
return (T)attributes?.FirstOrDefault(a => a is T);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReadonlyAttribute readonlyAttribute = GetAttribute<ReadonlyAttribute>();
|
||||||
|
|
||||||
|
ImGui.BeginDisabled(readonlyAttribute != null);
|
||||||
|
|
||||||
object newValue = DidNotChange;
|
object newValue = DidNotChange;
|
||||||
|
|
||||||
if (fieldType.IsGenericType)
|
if (fieldType.IsGenericType)
|
||||||
@@ -76,52 +87,102 @@ internal class EntityEditor
|
|||||||
{
|
{
|
||||||
ImGui.Text($"{fieldName} Primitive");
|
ImGui.Text($"{fieldName} Primitive");
|
||||||
|
|
||||||
|
unsafe void DragScalar<T>(ImGuiDataType dataType) where T : unmanaged
|
||||||
|
{
|
||||||
|
RangeAttribute range = GetAttribute<RangeAttribute>();
|
||||||
|
|
||||||
|
T min = default;
|
||||||
|
T max = default;
|
||||||
|
|
||||||
|
if (range != null)
|
||||||
|
{
|
||||||
|
min = (T)Convert.ChangeType(range.Min, typeof(T));
|
||||||
|
max = (T)Convert.ChangeType(range.Max, typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = (T)reference;
|
||||||
|
if (ImGui.DragScalar(fieldName, dataType, (IntPtr)(&value), 1, (IntPtr)(&min), (IntPtr)(&max)))
|
||||||
|
{
|
||||||
|
newValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (reference != null)
|
if (reference != null)
|
||||||
{
|
{
|
||||||
if (fieldType == typeof(float))
|
if (fieldType == typeof(bool))
|
||||||
{
|
|
||||||
float f = (float)reference;
|
|
||||||
if (ImGui.DragFloat(fieldName, ref f))
|
|
||||||
{
|
|
||||||
newValue = f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fieldType == typeof(int))
|
|
||||||
{
|
|
||||||
int f = (int)reference;
|
|
||||||
if (ImGui.DragInt(fieldName, ref f))
|
|
||||||
{
|
|
||||||
newValue = f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (fieldType == typeof(bool))
|
|
||||||
{
|
{
|
||||||
bool value = (bool)reference;
|
bool value = (bool)reference;
|
||||||
if (ImGui.Checkbox(fieldName, ref value))
|
if (ImGui.Checkbox(fieldName, ref value))
|
||||||
newValue = value;
|
newValue = value;
|
||||||
}
|
}
|
||||||
|
else if (fieldType == typeof(char))
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
char value = (char)reference;
|
||||||
|
|
||||||
// TODO: Do all the other types
|
if (ImGui.InputText(fieldName, (IntPtr)(&value), 2))
|
||||||
|
newValue = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fieldType == typeof(byte))
|
||||||
|
DragScalar<byte>(ImGuiDataType.U8);
|
||||||
|
else if (fieldType == typeof(sbyte))
|
||||||
|
DragScalar<sbyte>(ImGuiDataType.S8);
|
||||||
|
else if (fieldType == typeof(short))
|
||||||
|
DragScalar<short>(ImGuiDataType.S16);
|
||||||
|
else if (fieldType == typeof(ushort))
|
||||||
|
DragScalar<ushort>(ImGuiDataType.U16);
|
||||||
|
else if (fieldType == typeof(int))
|
||||||
|
DragScalar<int>(ImGuiDataType.S32);
|
||||||
|
else if (fieldType == typeof(uint))
|
||||||
|
DragScalar<uint>(ImGuiDataType.U32);
|
||||||
|
else if (fieldType == typeof(long))
|
||||||
|
DragScalar<long>(ImGuiDataType.S64);
|
||||||
|
else if (fieldType == typeof(ulong))
|
||||||
|
DragScalar<ulong>(ImGuiDataType.U64);
|
||||||
|
else if (fieldType == typeof(float))
|
||||||
|
DragScalar<float>(ImGuiDataType.Float);
|
||||||
|
else if (fieldType == typeof(double))
|
||||||
|
DragScalar<double>(ImGuiDataType.Double);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fieldType.IsValueType)
|
else if (fieldType.IsValueType)
|
||||||
{
|
{
|
||||||
|
if (fieldType == typeof(bool2))
|
||||||
|
{
|
||||||
|
bool2 value = (bool2)reference;
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(fieldName);
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Checkbox($"##{fieldName}X", ref value.X))
|
||||||
|
newValue = value;
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
if (ImGui.Checkbox($"##{fieldName}Y", ref value.Y))
|
||||||
|
newValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
// Struct
|
// Struct
|
||||||
if (ImGui.TreeNode(fieldName))
|
if (ImGui.TreeNode(fieldName))
|
||||||
{
|
{
|
||||||
//object @struct = (reference != null) ? field.GetValue(reference) : null;
|
ImGui.BeginDisabled(readonlyAttribute != null);
|
||||||
|
|
||||||
ShowEditor(fieldType, reference);
|
ShowEditor(fieldType, reference);
|
||||||
|
|
||||||
//if (@struct != null)
|
|
||||||
//{
|
|
||||||
// field.SetValue(reference, @struct);
|
|
||||||
//}
|
|
||||||
|
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
|
|
||||||
newValue = reference;
|
newValue = reference;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.BeginDisabled(readonlyAttribute != null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (fieldType.IsSubclassOf(typeof(Entity)) || fieldType == typeof(Entity))
|
else if (fieldType.IsSubclassOf(typeof(Entity)) || fieldType == typeof(Entity))
|
||||||
{
|
{
|
||||||
@@ -135,11 +196,12 @@ internal class EntityEditor
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
if (ImGui.TreeNode(fieldName))
|
if (ImGui.TreeNode(fieldName))
|
||||||
{
|
{
|
||||||
//object @class = (reference != null) ? field.GetValue(reference) : null;
|
ImGui.BeginDisabled(readonlyAttribute != null);
|
||||||
|
|
||||||
//if (@class == null)
|
|
||||||
if (reference == null)
|
if (reference == null)
|
||||||
{
|
{
|
||||||
ImGui.SameLine(ImGui.GetWindowContentRegionMax().X - ImGui.CalcTextSize("Create").X - 2 * ImGui.GetStyle().FramePadding.X);
|
ImGui.SameLine(ImGui.GetWindowContentRegionMax().X - ImGui.CalcTextSize("Create").X - 2 * ImGui.GetStyle().FramePadding.X);
|
||||||
@@ -152,7 +214,6 @@ internal class EntityEditor
|
|||||||
{
|
{
|
||||||
object instance = Activator.CreateInstance(t);
|
object instance = Activator.CreateInstance(t);
|
||||||
newValue = instance;
|
newValue = instance;
|
||||||
//field.SetValue(reference, instance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,11 +227,9 @@ internal class EntityEditor
|
|||||||
if (ImGui.SmallButton("Remove"))
|
if (ImGui.SmallButton("Remove"))
|
||||||
{
|
{
|
||||||
newValue = null;
|
newValue = null;
|
||||||
//field.SetValue(reference, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (@class == null)
|
|
||||||
if (reference == null)
|
if (reference == null)
|
||||||
ImGui.Text("(NULL)");
|
ImGui.Text("(NULL)");
|
||||||
else
|
else
|
||||||
@@ -178,8 +237,14 @@ internal class EntityEditor
|
|||||||
|
|
||||||
ImGui.TreePop();
|
ImGui.TreePop();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.BeginDisabled(readonlyAttribute != null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
return newValue;
|
return newValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,11 +264,13 @@ internal class EntityEditor
|
|||||||
|
|
||||||
if (ShowFieldInEditor(field))
|
if (ShowFieldInEditor(field))
|
||||||
{
|
{
|
||||||
Log.Info(field.Name);
|
//Log.Info(field.Name);
|
||||||
|
|
||||||
object value = field.GetValue(reference);
|
object value = field.GetValue(reference);
|
||||||
|
|
||||||
object newValue = ShowFieldEditor(value, value?.GetType() ?? field.FieldType, field.Name);
|
IEnumerable<Attribute> attributes = field.GetCustomAttributes();
|
||||||
|
|
||||||
|
object newValue = ShowFieldEditor(value, value?.GetType() ?? field.FieldType, field.Name, attributes);
|
||||||
|
|
||||||
if (newValue != DidNotChange)
|
if (newValue != DidNotChange)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,14 +2,17 @@ using System;
|
|||||||
|
|
||||||
namespace GlitchyEngine.Editor;
|
namespace GlitchyEngine.Editor;
|
||||||
|
|
||||||
//public sealed class RangeAttribute : Attribute
|
public sealed class RangeAttribute : Attribute
|
||||||
//{
|
{
|
||||||
// public float Min { get; set; }
|
public double Min { get; set; }
|
||||||
// public float Max { get; set; }
|
public double Max { get; set; }
|
||||||
|
|
||||||
// public RangeAttribute(float min, float max)
|
public RangeAttribute(double min, double max)
|
||||||
// {
|
{
|
||||||
// Min = min;
|
if (max < min)
|
||||||
// Max = max;
|
throw new ArgumentOutOfRangeException(nameof(max), $"{nameof(max)} must be larger than {nameof(min)}.");
|
||||||
// }
|
|
||||||
//}
|
Min = min;
|
||||||
|
Max = max;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Editor;
|
||||||
|
|
||||||
|
public sealed class ReadonlyAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using ImGuiNET;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Extensions;
|
||||||
|
|
||||||
|
public static class ImGuiDataTypeExtension
|
||||||
|
{
|
||||||
|
public static ImGuiDataType GetImGuiDataType(Type type)
|
||||||
|
{
|
||||||
|
if (type == typeof(byte))
|
||||||
|
return ImGuiDataType.U8;
|
||||||
|
if (type == typeof(ushort))
|
||||||
|
return ImGuiDataType.U16;
|
||||||
|
if (type == typeof(uint))
|
||||||
|
return ImGuiDataType.U32;
|
||||||
|
if (type == typeof(ulong))
|
||||||
|
return ImGuiDataType.U64;
|
||||||
|
|
||||||
|
if (type == typeof(sbyte))
|
||||||
|
return ImGuiDataType.S8;
|
||||||
|
if (type == typeof(short))
|
||||||
|
return ImGuiDataType.S16;
|
||||||
|
if (type == typeof(int))
|
||||||
|
return ImGuiDataType.S32;
|
||||||
|
if (type == typeof(long))
|
||||||
|
return ImGuiDataType.S64;
|
||||||
|
|
||||||
|
if (type == typeof(float))
|
||||||
|
return ImGuiDataType.Float;
|
||||||
|
if (type == typeof(double))
|
||||||
|
return ImGuiDataType.Double;
|
||||||
|
|
||||||
|
throw new ArgumentException("The type must be an integer or float type.", nameof(type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//namespace ImGuiNET;
|
||||||
|
|
||||||
|
//public static unsafe partial class ImGui
|
||||||
|
//{
|
||||||
|
// [DllImport("__Internal", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
// private static extern unsafe bool ImGui_EditFloat2(byte* label, ref float2 value, float2 resetValues, float dragSpeed, float columnWidth, float2 minValue, float2 maxValue, bool2 componentEnabled);
|
||||||
|
|
||||||
|
// public static bool EditFloat2(string label, ref float2 value, float2 resetValues = default, float dragSpeed = 0.1f,
|
||||||
|
// float columnWidth = 100f, float2 minValue = default, float2 maxValue = default)
|
||||||
|
// {
|
||||||
|
// byte* native_label;
|
||||||
|
// int label_byteCount = 0;
|
||||||
|
// if (label != null)
|
||||||
|
// {
|
||||||
|
// label_byteCount = Encoding.UTF8.GetByteCount(label);
|
||||||
|
// if (label_byteCount > Util.StackAllocationSizeLimit)
|
||||||
|
// {
|
||||||
|
// native_label = Util.Allocate(label_byteCount + 1);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// byte* native_label_stackBytes = stackalloc byte[label_byteCount + 1];
|
||||||
|
// native_label = native_label_stackBytes;
|
||||||
|
// }
|
||||||
|
// int native_label_offset = Util.GetUtf8(label, native_label, label_byteCount);
|
||||||
|
// native_label[native_label_offset] = 0;
|
||||||
|
// }
|
||||||
|
// else { native_label = null; }
|
||||||
|
|
||||||
|
// return ImGui_EditFloat2(native_label, ref value, resetValues, dragSpeed, columnWidth, minValue, maxValue, true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public static bool EditFloat2(string label, ref float2 value, float2 resetValues, float dragSpeed,
|
||||||
|
// float columnWidth, float2 minValue, float2 maxValue, bool2 componentEnabled)
|
||||||
|
// {
|
||||||
|
// return ImGui_EditFloat2(label, ref value, resetValues, dragSpeed, columnWidth, minValue, maxValue, true);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //ImGui_EditFloat2(char8* label, ref float2 value, float2 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float2 minValue = .Zero, float2 maxValue = .Zero, bool2 componentEnabled = true)
|
||||||
|
//}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||||
<RootNamespace>GlitchyEngine</RootNamespace>
|
<RootNamespace>GlitchyEngine</RootNamespace>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
|
|||||||
Reference in New Issue
Block a user