Пример #1
0
        public string ToFieldDeclaration(UnityFieldDetails fieldDetails)
        {
            switch (fieldDetails.FieldType)
            {
            case SingularFieldType singularFieldType:
                var uiType = GetUiFieldType(singularFieldType.ContainedType);
                return($"private readonly {uiType} {fieldDetails.CamelCaseName}Field;");

            case OptionFieldType optionFieldType:
                var innerUiType = GetUiFieldType(optionFieldType.ContainedType);
                var element     = optionFieldType.IsNullable ? "NullableVisualElement" : "OptionVisualElement";
                return($"private readonly {element}<{innerUiType}, {optionFieldType.ContainedType.FqnType}> {fieldDetails.CamelCaseName}Field;");

            case ListFieldType listFieldType:
                var innerListType = GetUiFieldType(listFieldType.ContainedType);
                return($"private readonly PaginatedListView<{innerListType}, {listFieldType.ContainedType.FqnType}> {fieldDetails.CamelCaseName}Field;");

            case MapFieldType mapFieldType:
                var innerKeyType   = GetUiFieldType(mapFieldType.KeyType);
                var innerValueType = GetUiFieldType(mapFieldType.ValueType);

                return
                    ($"private readonly PaginatedMapView<{innerKeyType}, {mapFieldType.KeyType.FqnType}, {innerValueType}, {mapFieldType.ValueType.FqnType}> {fieldDetails.CamelCaseName}Field;");

            default:
                throw new ArgumentException($"Unexpected field type: {fieldDetails.FieldType.GetType()}");
            }
        }
Пример #2
0
        public string ToUiFieldUpdate(UnityFieldDetails fieldDetails, string fieldParent)
        {
            var uiElementName = $"{fieldDetails.CamelCaseName}Field";

            switch (fieldDetails.FieldType)
            {
            case SingularFieldType singularFieldType:
                return(ContainedTypeToUiFieldUpdate(singularFieldType.ContainedType, uiElementName, $"{fieldParent}.{fieldDetails.PascalCaseName}"));

            case OptionFieldType optionFieldType:
            case ListFieldType listFieldType:
            case MapFieldType mapFieldType:
                return($"{uiElementName}.Update({fieldParent}.{fieldDetails.PascalCaseName});");

            default:
                throw new ArgumentException($"Unexpected field type: {fieldDetails.FieldType.GetType()}");
            }
        }
Пример #3
0
        public string ToUiFieldUpdate(UnityFieldDetails fieldDetails, string fieldParent)
        {
            var uiElementName = $"{fieldDetails.CamelCaseName}Field";

            switch (fieldDetails.FieldType)
            {
            case SingularFieldType singularFieldType:
                return(ContainedTypeToUiFieldUpdate(singularFieldType.ContainedType, uiElementName, $"{fieldParent}.{fieldDetails.PascalCaseName}"));

            case OptionFieldType optionFieldType:
                return($"{uiElementName}.Update({fieldParent}.{fieldDetails.PascalCaseName});");

            case ListFieldType listFieldType:
                return($"{uiElementName}.Update({fieldParent}.{fieldDetails.PascalCaseName});");

            default:
                // TODO: Maps.
                return("");
            }
        }
Пример #4
0
        public string ToFieldDeclaration(UnityFieldDetails fieldDetails)
        {
            switch (fieldDetails.FieldType)
            {
            case SingularFieldType singularFieldType:
                var uiType = GetUiFieldType(singularFieldType.ContainedType);
                return($"private readonly {uiType} {fieldDetails.CamelCaseName}Field;");

            case OptionFieldType optionFieldType:
                var innerUiType = GetUiFieldType(optionFieldType.ContainedType);
                var element     = optionFieldType.IsNullable ? "NullableVisualElement" : "OptionVisualElement";
                return($"private readonly {element}<{innerUiType}, {optionFieldType.ContainedType.FqnType}> {fieldDetails.CamelCaseName}Field;");

            case ListFieldType listFieldType:
                var innerListType = GetUiFieldType(listFieldType.ContainedType);
                return($"private readonly PaginatedListView<{innerListType}, {listFieldType.ContainedType.FqnType}> {fieldDetails.CamelCaseName}Field;");

            default:
                // TODO: Maps.
                return("");
            }
        }
        public static TypeBlock Generate(UnityFieldDetails fieldDetails, string qualifiedNamespace, string componentName)
        {
            var fieldName = fieldDetails.PascalCaseName;
            var typeName  = fieldDetails.Type;

            Logger.Trace($"Generating {qualifiedNamespace}.{componentName}.ReferenceTypeProviders.{fieldName}Provider static class.");

            return(Scope.Type($"public static class {fieldName}Provider", provider =>
            {
                provider.Line($@"
private static readonly Dictionary<uint, {typeName}> Storage = new Dictionary<uint, {typeName}>();
private static readonly Dictionary<uint, global::Unity.Entities.World> WorldMapping = new Dictionary<uint, global::Unity.Entities.World>();

private static uint nextHandle = 0;

public static uint Allocate(global::Unity.Entities.World world)
{{
    var handle = GetNextHandle();

    Storage.Add(handle, default({typeName}));
    WorldMapping.Add(handle, world);

    return handle;
}}

public static {typeName} Get(uint handle)
{{
    if (!Storage.TryGetValue(handle, out var value))
    {{
        throw new ArgumentException($""{fieldName}Provider does not contain handle {{handle}}"");
    }}

    return value;
}}

public static void Set(uint handle, {typeName} value)
{{
    if (!Storage.ContainsKey(handle))
    {{
        throw new ArgumentException($""{fieldName}Provider does not contain handle {{handle}}"");
    }}

    Storage[handle] = value;
}}

public static void Free(uint handle)
{{
    Storage.Remove(handle);
    WorldMapping.Remove(handle);
}}

public static void CleanDataInWorld(global::Unity.Entities.World world)
{{
    var handles = WorldMapping.Where(pair => pair.Value == world).Select(pair => pair.Key).ToList();

    foreach (var handle in handles)
    {{
        Free(handle);
    }}
}}

private static uint GetNextHandle()
{{
    nextHandle++;

    while (Storage.ContainsKey(nextHandle))
    {{
        nextHandle++;
    }}

    return nextHandle;
}}
");
            }));
        }
Пример #6
0
        public IEnumerable <string> ToFieldInitialisation(UnityFieldDetails fieldDetails, string parentContainer)
        {
            switch (fieldDetails.FieldType)
            {
            case SingularFieldType singularFieldType:
                var humanReadableName = Formatting.SnakeCaseToHumanReadable(fieldDetails.Name);

                foreach (var initializer in GetFieldInitializer(singularFieldType.ContainedType, $"{fieldDetails.CamelCaseName}Field", humanReadableName, false))
                {
                    yield return(initializer);
                }

                yield return($"{parentContainer}.Add({fieldDetails.CamelCaseName}Field);");

                break;

            case OptionFieldType optionFieldType:
                var innerUiType = GetUiFieldType(optionFieldType.ContainedType);

                foreach (var initializer in GetFieldInitializer(optionFieldType.ContainedType, $"{fieldDetails.CamelCaseName}InnerField", "Value"))
                {
                    yield return(initializer);
                }

                var element = optionFieldType.IsNullable ? "NullableVisualElement" : "OptionVisualElement";

                yield return
                    ($"{fieldDetails.CamelCaseName}Field = new {element}<{innerUiType}, {optionFieldType.ContainedType.FqnType}>(\"{Formatting.SnakeCaseToHumanReadable(fieldDetails.Name)}\", {fieldDetails.CamelCaseName}InnerField, (element, data) => {{ {ContainedTypeToUiFieldUpdate(optionFieldType.ContainedType, "element", "data")} }});");

                yield return($"{parentContainer}.Add({fieldDetails.CamelCaseName}Field);");

                break;

            case ListFieldType listFieldType:
                var innerListType = GetUiFieldType(listFieldType.ContainedType);

                yield return
                    ($"{fieldDetails.CamelCaseName}Field = new PaginatedListView<{innerListType}, {listFieldType.ContainedType.FqnType}>(\"{Formatting.SnakeCaseToHumanReadable(fieldDetails.Name)}\", () => {{");

                foreach (var initializer in GetFieldInitializer(listFieldType.ContainedType, "inner", ""))
                {
                    yield return(initializer);
                }

                yield return("return inner; }, (index, data, element) => {");

                // These lines are part of the binding.
                var labelBinding = listFieldType.ContainedType.Category == ValueType.Type ? "Label" : "label";
                yield return($"element.{labelBinding} = $\"Item {{index + 1}}\";");

                yield return(ContainedTypeToUiFieldUpdate(listFieldType.ContainedType, "element", "data"));

                yield return("});");

                yield return($"{parentContainer}.Add({fieldDetails.CamelCaseName}Field);");

                break;

            case MapFieldType mapFieldType:
                var innerKeyType   = GetUiFieldType(mapFieldType.KeyType);
                var innerValueType = GetUiFieldType(mapFieldType.ValueType);

                yield return
                    ($"{fieldDetails.CamelCaseName}Field = new PaginatedMapView<{innerKeyType}, {mapFieldType.KeyType.FqnType}, {innerValueType}, {mapFieldType.ValueType.FqnType}>(\"{Formatting.SnakeCaseToHumanReadable(fieldDetails.Name)}\",");

                yield return("() => {");

                foreach (var initializer in GetFieldInitializer(mapFieldType.KeyType, "inner", "Key"))
                {
                    yield return(initializer);
                }

                yield return($"return inner; }}, (data, element) => {{ {ContainedTypeToUiFieldUpdate(mapFieldType.KeyType, "element", "data")} }},");

                yield return("() => {");

                foreach (var initializer in GetFieldInitializer(mapFieldType.ValueType, "inner", "Value"))
                {
                    yield return(initializer);
                }

                yield return($"return inner; }}, (data, element) => {{ {ContainedTypeToUiFieldUpdate(mapFieldType.ValueType, "element", "data")} }});");

                yield return($"{parentContainer}.Add({fieldDetails.CamelCaseName}Field);");

                break;

            default:
                throw new ArgumentException($"Unexpected field type: {fieldDetails.FieldType.GetType()}");
            }
        }