Game.UI.Widgets.EnumFieldBuilders
Assembly:
Namespace: Game.UI.Widgets
Type: public class EnumFieldBuilders : IFieldBuilderFactory
Base: IFieldBuilderFactory
Summary:
Factory responsible for creating UI field builders for enum types. It detects enum types (including [Flags] enums), builds a cached list of EnumMember entries for use in EnumField or FlagsField widgets, and provides conversion helpers to normalize enum values to/from ulong so the UI can work with a consistent underlying representation. Honors HideInEditorAttribute on enum fields and uses LocalizedString.Value to localize enum member names. Caches constructed member lists in a static dictionary (kMemberCache) keyed by the enum Type.
Fields
public static readonly System.Collections.Generic.Dictionary<Type, EnumMember[]> kMemberCache
Cache mapping enum Type -> array of EnumMember used by enum UI fields. Built on first use for each enum type to avoid repeated reflection. Note: this is a plain Dictionary with no synchronization for writes — races could theoretically occur if accessed concurrently from multiple threads during initial population.
Properties
- This type has no public properties.
Constructors
public EnumFieldBuilders()
Implicit default constructor. No special initialization is required — the class is stateless aside from the static kMemberCache.
Methods
public FieldBuilder TryCreate(Type memberType, object[] attributes)
Attempts to create a FieldBuilder for the provided type. Returns null if the type is not an enum or if a supported converter between the enum's underlying type and ulong cannot be produced. For supported enums it:- Retrieves or builds a cached EnumMember[] for the enum.
- If the enum has [Flags], returns a builder that creates a FlagsField; otherwise returns one that creates an EnumField.
-
Wraps the provided IValueAccessor with a CastAccessor
using the produced converters so the UI widgets operate on normalized ulong values. -
private static EnumMember[] BuildMembers(Type memberType, Converter<object, ulong> fromObject)
Collects the public static fields of the enum type (BindingFlags.Static | BindingFlags.Public), filtering out fields marked with HideInEditorAttribute. Converts each enum value to ulong using fromObject and constructs an EnumMember with the localized name obtained from LocalizedString.Value(fieldInfo.Name). For [Flags] enums, members with value zero are omitted. -
public static bool GetConverters(Type memberType, out Converter<object, ulong> fromObject, out Converter<ulong, object> toObject)
Produces converter delegates to normalize values between the enum's underlying integral type and ulong, and back. Supports sbyte, byte, short, ushort, int, uint, long, and ulong underlying types. Returns false (and sets converters to null) if the underlying type is not one of the supported types.
Behavior notes: - The class normalizes enum values through ulong so that different underlying integral enum types can be handled uniformly. - For [Flags] enums, zero-valued members are skipped to avoid presenting a meaningless "none" option in the flags UI. - Enum member display names are localized using LocalizedString.Value on the field name. - If GetConverters returns false, TryCreate will not create a builder for that enum type.
Usage Example
// Example: creating a field builder for a given enum type and building the UI widget.
var factory = new EnumFieldBuilders();
Type enumType = typeof(MyModNamespace.MyEnum);
// No attributes in this example
FieldBuilder builder = factory.TryCreate(enumType, new object[0]);
if (builder != null)
{
// IValueAccessor is part of the UI system; you would provide an accessor tied to your data model.
IValueAccessor accessor = /* obtain or create accessor for your enum-backed value */;
// The builder returns an EnumField or FlagsField configured for the enum.
var fieldWidget = builder(accessor);
// Add fieldWidget to your editor UI as appropriate...
}
else
{
// enumType isn't supported (e.g. unsupported underlying type) or isn't an enum
}
Additional modding tips: - If you want an enum value hidden from the editor, annotate the enum field with HideInEditorAttribute. - Ensure enum underlying types are one of: sbyte, byte, short, ushort, int, uint, long, ulong. Otherwise the factory will not create a field builder. - Be aware of potential concurrent initialization of kMemberCache if invoking TryCreate for new enum types from multiple threads; consider pre-warming the cache on the main thread if needed.