Show enum fields in Edit mode

This commit is contained in:
Simon Lübeß
2023-07-28 00:07:10 +02:00
parent 1254d01545
commit f39acdadb3
5 changed files with 143 additions and 36 deletions
@@ -11,9 +11,9 @@ namespace Sandbox
public enum MyEnum
{
Yes,
Yes = 1,
No,
Maybe
Maybe = 1337
}
public struct MyStruct
@@ -53,7 +53,9 @@ namespace Sandbox
[ShowInEditor] private int MyNumber = 1337;
//[ShowInEditor] public double MyDouble = 1000.0f;
//public MyStruct AStruct;
public MyStruct AStruct;
public MyEnum AEnum = MyEnum.Maybe;
public Camera Camera;
@@ -693,8 +693,7 @@ namespace GlitchyEditor.EditWindows
field.SetData(value);
case .Enum:
// TODO!
ShowEnumSelector(field, fieldName, scriptClass);
//case .String:
// TODO!
@@ -716,6 +715,33 @@ namespace GlitchyEditor.EditWindows
}
}
private static void ShowEnumSelector(ScriptFieldInstance* field, StringView fieldName, ScriptClass scriptClass)
{
ScriptField scriptField = scriptClass.Fields[fieldName];
SharpEnum enumType = scriptField.SharpType as SharpEnum;
Log.EngineLogger.Assert(enumType != null, "Enum must have a SharpEnum!");
// Simply get Enum as a uint64
var fieldValue = field.GetData<uint64>();
StringView valueName = "<Invalid Value>";
if (enumType.Values.TryGetValue(fieldValue, let enumValue))
valueName = enumValue.Name;
if (ImGui.BeginCombo(fieldName.Ptr, valueName.Ptr))
{
for (let (entryValue, enumEntry) in enumType.Values)
{
if (ImGui.Selectable(enumEntry.Name.Ptr, fieldValue == entryValue))
field.SetData(entryValue);
}
ImGui.EndCombo();
}
}
private static Entity? ShowEntitySelector()
{
static char8[128] entitySearch = .();
+66 -3
View File
@@ -13,13 +13,15 @@ public struct ScriptField
internal MonoClassField* _monoField;
public bool IsStatic;
public ScriptFieldType FieldType;
public SharpType SharpType;
internal this(StringView name, MonoClassField* monoField, bool isStatic, ScriptFieldType fieldType)
internal this(StringView name, MonoClassField* monoField, bool isStatic, ScriptFieldType fieldType, SharpType sharpType)
{
Name = name;
_monoField = monoField;
IsStatic = isStatic;
FieldType = fieldType;
SharpType = sharpType;
}
public bool IsType(SharpClass otherClass, bool checkIfSubtype)
@@ -147,10 +149,12 @@ class SharpClass : SharpType
ScriptFieldType fieldType = ScriptEngineHelper.GetScriptFieldType(type);
SharpType sharpType = null;
// If field type is none the field might be a struct, class or enum
if (fieldType == .None)
{
SharpType sharpType = ScriptEngine.GetSharpType(type);
sharpType = ScriptEngine.GetSharpType(type);
fieldType = sharpType?.ScriptType ?? .None;
if (sharpType == null)
@@ -169,7 +173,66 @@ class SharpClass : SharpType
(attributes != null &&
Mono.mono_custom_attrs_has_attr(attributes, ScriptEngine.Attributes.s_ShowInEditorAttribute)))
{
_monoFields[name] = .(name, currentField, flags.HasFlag(.Static), fieldType);
_monoFields[name] = .(name, currentField, flags.HasFlag(.Static), fieldType, sharpType);
}
}
}
}
struct EnumValue
{
public StringView Name;
public uint64 Value;
public this(StringView name, uint64 value)
{
Name = name;
Value = value;
}
}
class SharpEnum : SharpClass
{
private append Dictionary<uint64, EnumValue> _values = .();
public Dictionary<uint64, EnumValue> Values => _values;
private int _underlyingSize = 0;
public this(StringView classNamespace, StringView className, MonoImage* image)
: base(classNamespace, className, image, .Enum)
{
ExtractEnumValues();
}
private void ExtractEnumValues()
{
_underlyingSize = Mono.mono_class_instance_size(_monoClass);
Log.EngineLogger.Assert(_underlyingSize != 0);
var vtable = Mono.mono_class_vtable(ScriptEngine.[Friend]s_AppDomain, _monoClass);
void* iterator = null;
MonoClassField* currentField = null;
while ((currentField = Mono.mono_class_get_fields(_monoClass, &iterator)) != null)
{
MonoType* fieldType = Mono.mono_field_get_type(currentField);
MonoClass* fieldClass = Mono.mono_type_get_class(fieldType);
FieldAttribute fieldFlags = (.)Mono.mono_field_get_flags(currentField);
if (fieldFlags.HasFlag(.Public) && fieldFlags.HasFlag(.Static) &&
fieldClass != null && Mono.mono_class_is_subclass_of(fieldClass, _monoClass, false))
{
StringView fieldName = StringView(Mono.mono_field_get_name(currentField));
uint64 value = 0;
Mono.mono_field_static_get_value(vtable, currentField, &value);
EnumValue enumValue = .(fieldName, value);
_values.Add(value, enumValue);
}
}
}
+28 -28
View File
@@ -461,37 +461,37 @@ static class ScriptEngine
//if (classNamespace.StartsWith("GlitchyEngine"))
// return null;
switch (fieldType)
ScriptFieldType scriptType = .None;
if (Mono.mono_class_is_enum(monoClass))
{
case .Class, .Valuetype, .Enum:
ScriptFieldType scriptType = .None;
scriptType = .Enum;
if (fieldType == .Class)
{
if (Mono.mono_class_is_subclass_of(monoClass, s_EntityRoot._monoClass, false))
{
scriptType = .Entity;
}
else if (Mono.mono_class_is_subclass_of(monoClass, s_ComponentRoot._monoClass, false))
{
scriptType = .Component;
}
else
{
scriptType = .Class;
}
}
else if (fieldType == .Enum)
scriptType = .Enum;
else if (fieldType == .Valuetype)
scriptType = .Struct;
Log.EngineLogger.AssertDebug(scriptType != .None);
return new SharpClass(classNamespace, className, Mono.mono_class_get_image(monoClass), scriptType);
default:
return null;
return new SharpEnum(classNamespace, className, Mono.mono_class_get_image(monoClass));
}
else if (fieldType == .Class)
{
if (Mono.mono_class_is_subclass_of(monoClass, s_EntityRoot._monoClass, false))
{
scriptType = .Entity;
}
else if (Mono.mono_class_is_subclass_of(monoClass, s_ComponentRoot._monoClass, false))
{
scriptType = .Component;
}
else
{
scriptType = .Class;
}
}
else if (fieldType == .Valuetype)
{
scriptType = .Struct;
}
Log.EngineLogger.AssertDebug(scriptType != .None);
return new SharpClass(classNamespace, className, Mono.mono_class_get_image(monoClass), scriptType);
}
public static void CreateScriptFieldMap(Entity entity)
+16
View File
@@ -92,6 +92,9 @@ static class Mono
[LinkName(.C)]
public static extern MonoType* mono_class_get_type(MonoClass* monoClass);
[LinkName(.C)]
public static extern int32 mono_class_instance_size(MonoClass* @class);
[LinkName(.C)]
public static extern char8* mono_class_get_namespace(MonoClass* monoClass);
@@ -182,6 +185,9 @@ static class Mono
[LinkName(.C)]
public static extern void mono_field_get_value(MonoObject* object, MonoClassField* field, void* value);
[LinkName(.C)]
public static extern void mono_field_static_get_value(MonoVTable* vt, MonoClassField* field, void* value);
/// Gets the field as object, boxes the value if it is a valuetype.
[LinkName(.C)]
public static extern MonoObject* mono_field_get_value_object(MonoDomain* domain, MonoClassField* field, MonoObject* obj);
@@ -251,6 +257,14 @@ static class Mono
[LinkName(.C)]
public static extern MonoClass* mono_object_get_class(MonoObject* obj);
[LinkName(.C)]
public static extern mono_bool mono_class_is_enum(MonoClass* @class);
[LinkName(.C)]
public static extern MonoVTable* mono_class_vtable(MonoDomain* domain, MonoClass* @class);
}
struct MonoDomain;
@@ -273,6 +287,8 @@ struct MonoProperty;
struct MonoThread;
struct MonoVTable;
struct MonoException
{
void* _bla;