mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Show enum fields in Edit mode
This commit is contained in:
@@ -11,9 +11,9 @@ namespace Sandbox
|
|||||||
|
|
||||||
public enum MyEnum
|
public enum MyEnum
|
||||||
{
|
{
|
||||||
Yes,
|
Yes = 1,
|
||||||
No,
|
No,
|
||||||
Maybe
|
Maybe = 1337
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MyStruct
|
public struct MyStruct
|
||||||
@@ -53,7 +53,9 @@ namespace Sandbox
|
|||||||
[ShowInEditor] private int MyNumber = 1337;
|
[ShowInEditor] private int MyNumber = 1337;
|
||||||
//[ShowInEditor] public double MyDouble = 1000.0f;
|
//[ShowInEditor] public double MyDouble = 1000.0f;
|
||||||
|
|
||||||
//public MyStruct AStruct;
|
public MyStruct AStruct;
|
||||||
|
|
||||||
|
public MyEnum AEnum = MyEnum.Maybe;
|
||||||
|
|
||||||
public Camera Camera;
|
public Camera Camera;
|
||||||
|
|
||||||
|
|||||||
@@ -693,8 +693,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
field.SetData(value);
|
field.SetData(value);
|
||||||
|
|
||||||
case .Enum:
|
case .Enum:
|
||||||
// TODO!
|
ShowEnumSelector(field, fieldName, scriptClass);
|
||||||
|
|
||||||
//case .String:
|
//case .String:
|
||||||
// TODO!
|
// 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()
|
private static Entity? ShowEntitySelector()
|
||||||
{
|
{
|
||||||
static char8[128] entitySearch = .();
|
static char8[128] entitySearch = .();
|
||||||
|
|||||||
@@ -13,13 +13,15 @@ public struct ScriptField
|
|||||||
internal MonoClassField* _monoField;
|
internal MonoClassField* _monoField;
|
||||||
public bool IsStatic;
|
public bool IsStatic;
|
||||||
public ScriptFieldType FieldType;
|
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;
|
Name = name;
|
||||||
_monoField = monoField;
|
_monoField = monoField;
|
||||||
IsStatic = isStatic;
|
IsStatic = isStatic;
|
||||||
FieldType = fieldType;
|
FieldType = fieldType;
|
||||||
|
SharpType = sharpType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsType(SharpClass otherClass, bool checkIfSubtype)
|
public bool IsType(SharpClass otherClass, bool checkIfSubtype)
|
||||||
@@ -147,10 +149,12 @@ class SharpClass : SharpType
|
|||||||
|
|
||||||
ScriptFieldType fieldType = ScriptEngineHelper.GetScriptFieldType(type);
|
ScriptFieldType fieldType = ScriptEngineHelper.GetScriptFieldType(type);
|
||||||
|
|
||||||
|
SharpType sharpType = null;
|
||||||
|
|
||||||
// If field type is none the field might be a struct, class or enum
|
// If field type is none the field might be a struct, class or enum
|
||||||
if (fieldType == .None)
|
if (fieldType == .None)
|
||||||
{
|
{
|
||||||
SharpType sharpType = ScriptEngine.GetSharpType(type);
|
sharpType = ScriptEngine.GetSharpType(type);
|
||||||
fieldType = sharpType?.ScriptType ?? .None;
|
fieldType = sharpType?.ScriptType ?? .None;
|
||||||
|
|
||||||
if (sharpType == null)
|
if (sharpType == null)
|
||||||
@@ -169,7 +173,66 @@ class SharpClass : SharpType
|
|||||||
(attributes != null &&
|
(attributes != null &&
|
||||||
Mono.mono_custom_attrs_has_attr(attributes, ScriptEngine.Attributes.s_ShowInEditorAttribute)))
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -461,12 +461,15 @@ static class ScriptEngine
|
|||||||
//if (classNamespace.StartsWith("GlitchyEngine"))
|
//if (classNamespace.StartsWith("GlitchyEngine"))
|
||||||
// return null;
|
// return null;
|
||||||
|
|
||||||
switch (fieldType)
|
|
||||||
{
|
|
||||||
case .Class, .Valuetype, .Enum:
|
|
||||||
ScriptFieldType scriptType = .None;
|
ScriptFieldType scriptType = .None;
|
||||||
|
|
||||||
if (fieldType == .Class)
|
if (Mono.mono_class_is_enum(monoClass))
|
||||||
|
{
|
||||||
|
scriptType = .Enum;
|
||||||
|
|
||||||
|
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))
|
if (Mono.mono_class_is_subclass_of(monoClass, s_EntityRoot._monoClass, false))
|
||||||
{
|
{
|
||||||
@@ -481,17 +484,14 @@ static class ScriptEngine
|
|||||||
scriptType = .Class;
|
scriptType = .Class;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fieldType == .Enum)
|
|
||||||
scriptType = .Enum;
|
|
||||||
else if (fieldType == .Valuetype)
|
else if (fieldType == .Valuetype)
|
||||||
|
{
|
||||||
scriptType = .Struct;
|
scriptType = .Struct;
|
||||||
|
}
|
||||||
|
|
||||||
Log.EngineLogger.AssertDebug(scriptType != .None);
|
Log.EngineLogger.AssertDebug(scriptType != .None);
|
||||||
|
|
||||||
return new SharpClass(classNamespace, className, Mono.mono_class_get_image(monoClass), scriptType);
|
return new SharpClass(classNamespace, className, Mono.mono_class_get_image(monoClass), scriptType);
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void CreateScriptFieldMap(Entity entity)
|
public static void CreateScriptFieldMap(Entity entity)
|
||||||
|
|||||||
@@ -92,6 +92,9 @@ static class Mono
|
|||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoType* mono_class_get_type(MonoClass* monoClass);
|
public static extern MonoType* mono_class_get_type(MonoClass* monoClass);
|
||||||
|
|
||||||
|
[LinkName(.C)]
|
||||||
|
public static extern int32 mono_class_instance_size(MonoClass* @class);
|
||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern char8* mono_class_get_namespace(MonoClass* monoClass);
|
public static extern char8* mono_class_get_namespace(MonoClass* monoClass);
|
||||||
|
|
||||||
@@ -182,6 +185,9 @@ static class Mono
|
|||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern void mono_field_get_value(MonoObject* object, MonoClassField* field, void* value);
|
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.
|
/// Gets the field as object, boxes the value if it is a valuetype.
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoObject* mono_field_get_value_object(MonoDomain* domain, MonoClassField* field, MonoObject* obj);
|
public static extern MonoObject* mono_field_get_value_object(MonoDomain* domain, MonoClassField* field, MonoObject* obj);
|
||||||
@@ -251,6 +257,14 @@ static class Mono
|
|||||||
|
|
||||||
[LinkName(.C)]
|
[LinkName(.C)]
|
||||||
public static extern MonoClass* mono_object_get_class(MonoObject* obj);
|
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;
|
struct MonoDomain;
|
||||||
@@ -273,6 +287,8 @@ struct MonoProperty;
|
|||||||
|
|
||||||
struct MonoThread;
|
struct MonoThread;
|
||||||
|
|
||||||
|
struct MonoVTable;
|
||||||
|
|
||||||
struct MonoException
|
struct MonoException
|
||||||
{
|
{
|
||||||
void* _bla;
|
void* _bla;
|
||||||
|
|||||||
Reference in New Issue
Block a user