diff --git a/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs b/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs index eb35bec..128ef98 100644 --- a/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs +++ b/Upsilon/BaseTypes/UserData/UserDataTypeHandler.cs @@ -11,7 +11,16 @@ namespace Upsilon.BaseTypes.UserData { var info = new UserDataType(t); _types.Add(t, info); - BoundTypeHandler.LoadUserDataTypeDefinition(new UserDataBoundTypeDefinition(t)); + UserDataBoundTypeDefinition boundType; + if (t.IsEnum) + { + boundType = new UserDataBoundEnumDefinition(t); + } + else + { + boundType = UserDataBoundTypeDefinition.Create(t); + } + BoundTypeHandler.LoadUserDataTypeDefinition(boundType); } public static void LoadType() diff --git a/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs b/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs index 9343c95..cdae7b8 100644 --- a/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs +++ b/Upsilon/BoundTypes/UserDataBoundTypeDefinition.cs @@ -1,28 +1,37 @@ +using System; using System.Collections.Generic; using System.Linq; using Upsilon.BaseTypes; +using Type = Upsilon.BaseTypes.Type; namespace Upsilon.BoundTypes { public class UserDataBoundTypeDefinition : BoundTypeDefinition { public string Name { get; } - public Dictionary Properties { get; } + public Dictionary Properties { get; protected set; } - public UserDataBoundTypeDefinition(System.Type backingType) + internal UserDataBoundTypeDefinition(System.Type backingType) : base(Type.UserData, backingType) { Name = backingType.Name; - Properties = new Dictionary(); + } + + public static UserDataBoundTypeDefinition Create(System.Type backingType) + { + var obj = new UserDataBoundTypeDefinition(backingType) + { + Properties = new Dictionary() + }; var fields = backingType.GetFields().Select(x => new UserDataBoundProperty() { - Name = x.Name, + Name = x.Name, ActualType = x.FieldType.Name, - Type = x.FieldType.GetScriptType(), + Type = x.FieldType.GetScriptType(), }); foreach (var f in fields) { - Properties.Add(f.Name.ToLowerInvariant(), f); + obj.Properties.Add(f.Name.ToLowerInvariant(), f); } var properties = backingType.GetProperties().Select(x => new UserDataBoundProperty() { @@ -32,7 +41,7 @@ namespace Upsilon.BoundTypes }); foreach (var f in properties) { - Properties.Add(f.Name.ToLowerInvariant(), f); + obj.Properties.Add(f.Name.ToLowerInvariant(), f); } var methods = backingType.GetMethods().Select(x => new UserDataBoundMethod() { @@ -42,16 +51,39 @@ namespace Upsilon.BoundTypes }); foreach (var f in methods) { - Properties.Add(f.Name.ToLowerInvariant(), f); + obj.Properties.Add(f.Name.ToLowerInvariant(), f); } + return obj; } + } - public UserDataBoundTypeDefinition(string name, Dictionary properties) - : base(Type.UserData, new System.Type[0]) + public class UserDataBoundEnumDefinition : UserDataBoundTypeDefinition + { + public UserDataBoundEnumDefinition(System.Type enumType) : base(enumType) { - Name = name; - Properties = properties; + if (!enumType.IsEnum) + throw new Exception("Trying to bind an enum with a type that's not an enum"); + + Properties = new Dictionary(); + var enumUnderlyingType = Enum.GetUnderlyingType(enumType); + var enumValues = Enum.GetValues(enumType); + + for (var i=0; i < enumValues.Length; i++) + { + // Retrieve the value of the ith enum item. + var value = enumValues.GetValue(i); + + // Convert the value to its underlying type (int, byte, long, ...) + var underlyingValue = Convert.ChangeType(value, enumUnderlyingType); + var name = value.ToString().ToLowerInvariant(); + Properties.Add(name, new UserDataBoundProperty() + { + Name = name, + ActualType = enumUnderlyingType.ToString(), + Type = Type.Number + }); + } } } diff --git a/Upsilon/StandardLibraries/StaticScope.cs b/Upsilon/StandardLibraries/StaticScope.cs index 5180a47..289cae2 100644 --- a/Upsilon/StandardLibraries/StaticScope.cs +++ b/Upsilon/StandardLibraries/StaticScope.cs @@ -95,6 +95,8 @@ namespace Upsilon.StandardLibraries if (type == typeof(ScriptType)) // allows every type return (Type) 255; + if (type.IsEnum) + return Type.Number; return Type.UserData; } }