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
|
||||
{
|
||||
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 = .();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -460,38 +460,38 @@ static class ScriptEngine
|
||||
// TODO: at the moment only allow user-structs
|
||||
//if (classNamespace.StartsWith("GlitchyEngine"))
|
||||
// return null;
|
||||
|
||||
ScriptFieldType scriptType = .None;
|
||||
|
||||
switch (fieldType)
|
||||
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)
|
||||
|
||||
@@ -91,6 +91,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);
|
||||
@@ -181,6 +184,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)]
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user