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()}"); } }
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()}"); } }
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(""); } }
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; }} "); })); }
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()}"); } }