From e5a7da3cd5a7a7fa01cbe25f7d58d409c65f88d9 Mon Sep 17 00:00:00 2001 From: Jamie Brynes Date: Wed, 10 Jun 2020 12:01:52 +0100 Subject: [PATCH 1/6] expose some more info in code generation lib --- .../Model/Details/FieldTypes/ContainedType.cs | 4 ++++ .../Model/Details/TypeDetails/UnityTypeDetails.cs | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/FieldTypes/ContainedType.cs b/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/FieldTypes/ContainedType.cs index 22c24751ce..65834883d1 100644 --- a/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/FieldTypes/ContainedType.cs +++ b/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/FieldTypes/ContainedType.cs @@ -6,6 +6,7 @@ namespace Improbable.Gdk.CodeGeneration.Model.Details public class ContainedType { public readonly string FqnType; + public readonly string RawType; public readonly ValueType Category; public readonly PrimitiveType? PrimitiveType; @@ -16,16 +17,19 @@ public ContainedType(TypeReference innerType) case ValueType.Enum: Category = ValueType.Enum; FqnType = DetailsUtils.GetCapitalisedFqnTypename(innerType.Enum); + RawType = innerType.Enum; PrimitiveType = null; break; case ValueType.Primitive: Category = ValueType.Primitive; FqnType = UnityTypeMappings.SchemaTypeToUnityType[innerType.Primitive]; + RawType = innerType.Primitive.ToString(); PrimitiveType = innerType.Primitive; break; case ValueType.Type: Category = ValueType.Type; FqnType = DetailsUtils.GetCapitalisedFqnTypename(innerType.Type); + RawType = innerType.Type; PrimitiveType = null; break; default: diff --git a/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/TypeDetails/UnityTypeDetails.cs b/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/TypeDetails/UnityTypeDetails.cs index 55dc8614c6..46bf9e76c3 100644 --- a/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/TypeDetails/UnityTypeDetails.cs +++ b/workers/unity/Packages/io.improbable.gdk.tools/.CodeGenTemplate/CodeGenerationLib/Model/Details/TypeDetails/UnityTypeDetails.cs @@ -14,6 +14,8 @@ public class UnityTypeDetails : GeneratorInputDetails public IReadOnlyList ChildTypes { get; private set; } public IReadOnlyList ChildEnums { get; private set; } + public UnityTypeDetails Parent { get; private set; } + public SerializationOverride SerializationOverride { get; internal set; } public bool HasSerializationOverride => SerializationOverride != null; @@ -45,6 +47,11 @@ private void PopulateChildren(DetailsStore store) .ToList() .AsReadOnly(); + foreach (var child in ChildTypes) + { + child.Parent = this; + } + Logger.Trace($"Populating child enum details for type {rawTypeDefinition.QualifiedName}."); ChildEnums = store.Enums .Where(kv => children.Contains(kv.Key)) From 76bd5e2df225ed844d6567c8c416eb8810bd14cd Mon Sep 17 00:00:00 2001 From: Jamie Brynes Date: Wed, 10 Jun 2020 12:01:14 +0100 Subject: [PATCH 2/6] refactor out FieldTypeHandler & add type support --- .../ComponentVisualElementGenerator.cs | 172 ++------------- .../DebugExtensions/FieldTypeHandler.cs | 200 ++++++++++++++++++ 2 files changed, 214 insertions(+), 158 deletions(-) create mode 100644 workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/FieldTypeHandler.cs diff --git a/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/ComponentVisualElementGenerator.cs b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/ComponentVisualElementGenerator.cs index 274cfab041..640ecf6415 100644 --- a/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/ComponentVisualElementGenerator.cs +++ b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/ComponentVisualElementGenerator.cs @@ -1,18 +1,20 @@ -using System; -using System.Collections.Generic; using System.Linq; using Improbable.Gdk.CodeGeneration.CodeWriter; using Improbable.Gdk.CodeGeneration.CodeWriter.Scopes; -using Improbable.Gdk.CodeGeneration.Model; using Improbable.Gdk.CodeGeneration.Model.Details; -using Improbable.Gdk.CodeGeneration.Utils; -using ValueType = Improbable.Gdk.CodeGeneration.Model.ValueType; namespace Improbable.Gdk.CodeGenerator { - public static class ComponentVisualElementGenerator + public class ComponentVisualElementGenerator { - public static CodeWriter Generate(UnityComponentDetails details) + private readonly FieldTypeHandler typeGenerator; + + public ComponentVisualElementGenerator(DetailsStore detailsStore) + { + typeGenerator = new FieldTypeHandler(detailsStore); + } + + public CodeWriter Generate(UnityComponentDetails details) { return CodeWriter.Populate(cgw => { @@ -29,7 +31,7 @@ public static CodeWriter Generate(UnityComponentDetails details) { type.Line($"public override ComponentType ComponentType {{ get; }} = ComponentType.ReadOnly<{details.Name}.Component>();"); - type.TextList(details.FieldDetails.Select(ToFieldDeclaration)); + type.TextList(details.FieldDetails.Select(typeGenerator.ToFieldDeclaration)); GenerateConstructor(type, details); GenerateUpdateMethod(type, details); @@ -38,27 +40,7 @@ public static CodeWriter Generate(UnityComponentDetails details) }); } - private static string ToFieldDeclaration(UnityFieldDetails fieldDetails) - { - switch (fieldDetails.FieldType) - { - case SingularFieldType singularFieldType: - var uiType = GetUiFieldType(singularFieldType.ContainedType); - - if (uiType == "") - { - // TODO: Eliminate this case. - return ""; - } - - return $"private readonly {uiType} {fieldDetails.CamelCaseName}Field;"; - default: - // TODO: Lists, maps, and options - return ""; - } - } - - private static void GenerateConstructor(TypeBlock typeBlock, UnityComponentDetails details) + private void GenerateConstructor(TypeBlock typeBlock, UnityComponentDetails details) { typeBlock.Method($"public {details.Name}Renderer() : base()", mb => { @@ -67,146 +49,20 @@ private static void GenerateConstructor(TypeBlock typeBlock, UnityComponentDetai foreach (var field in details.FieldDetails) { - mb.TextList(ToFieldInitialisation(field)); + mb.TextList(typeGenerator.ToFieldInitialisation(field, "ComponentFoldout")); } }); } - private static IEnumerable ToFieldInitialisation(UnityFieldDetails fieldDetails) - { - switch (fieldDetails.FieldType) - { - case SingularFieldType singularFieldType: - - var uiType = GetUiFieldType(singularFieldType.ContainedType); - - if (uiType == "") - { - // TODO: Eliminate this case. - yield break; - } - - var humanReadableName = Formatting.SnakeCaseToHumanReadable(fieldDetails.Name); - yield return $"{fieldDetails.CamelCaseName}Field = new {uiType}(\"{humanReadableName}\");"; - yield return $"{fieldDetails.CamelCaseName}Field.SetEnabled(false);"; - - if (singularFieldType.ContainedType.Category == ValueType.Enum) - { - yield return $"{fieldDetails.CamelCaseName}Field.Init(default({fieldDetails.Type}));"; - } - - yield return $"ComponentFoldout.Add({fieldDetails.CamelCaseName}Field);"; - break; - default: - // TODO: Lists, maps, and options - yield break; - } - } - - private static void GenerateUpdateMethod(TypeBlock typeBlock, UnityComponentDetails details) + private void GenerateUpdateMethod(TypeBlock typeBlock, UnityComponentDetails details) { typeBlock.Method("public override void Update(EntityManager manager, Entity entity)", mb => { mb.Line($"AuthoritativeToggle.value = manager.HasComponent<{details.Name}.HasAuthority>(entity);"); mb.Line($"var component = manager.GetComponentData<{details.Name}.Component>(entity);"); - mb.TextList(TextList.New(details.FieldDetails.Select(ToUiFieldUpdate))); + mb.TextList(details.FieldDetails.Select(fd => typeGenerator.ToUiFieldUpdate(fd, "component"))); }); } - - private static string ToUiFieldUpdate(UnityFieldDetails fieldDetails) - { - switch (fieldDetails.FieldType) - { - case SingularFieldType singularFieldType: - switch (singularFieldType.ContainedType.Category) - { - case ValueType.Enum: - return $"{fieldDetails.CamelCaseName}Field.value = component.{fieldDetails.PascalCaseName};"; - case ValueType.Primitive: - var primitiveType = singularFieldType.ContainedType.PrimitiveType.Value; - - switch (primitiveType) - { - case PrimitiveType.Int32: - case PrimitiveType.Int64: - case PrimitiveType.Uint32: - case PrimitiveType.Uint64: - case PrimitiveType.Sint32: - case PrimitiveType.Sint64: - case PrimitiveType.Fixed32: - case PrimitiveType.Fixed64: - case PrimitiveType.Sfixed32: - case PrimitiveType.Sfixed64: - case PrimitiveType.Float: - case PrimitiveType.Double: - case PrimitiveType.String: - case PrimitiveType.EntityId: - return $"{fieldDetails.CamelCaseName}Field.value = component.{fieldDetails.PascalCaseName}.ToString();"; - case PrimitiveType.Bytes: - return $"{fieldDetails.CamelCaseName}Field.value = global::System.Text.Encoding.Default.GetString(component.{fieldDetails.PascalCaseName});"; - case PrimitiveType.Bool: - return $"{fieldDetails.CamelCaseName}Field.value = component.{fieldDetails.PascalCaseName};"; - break; - case PrimitiveType.Entity: - // TODO: Entity type. - return ""; - case PrimitiveType.Invalid: - throw new ArgumentException("Unknown primitive type encountered"); - default: - throw new ArgumentOutOfRangeException(); - } - case ValueType.Type: - // TODO: User defined types. - return ""; - default: - throw new ArgumentOutOfRangeException(); - } - default: - // TODO: Lists, maps, and options - return ""; - } - } - - private static string GetUiFieldType(ContainedType type) - { - switch (type.Category) - { - case ValueType.Enum: - return "EnumField"; - case ValueType.Primitive: - switch (type.PrimitiveType.Value) - { - case PrimitiveType.Int32: - case PrimitiveType.Int64: - case PrimitiveType.Uint32: - case PrimitiveType.Uint64: - case PrimitiveType.Sint32: - case PrimitiveType.Sint64: - case PrimitiveType.Fixed32: - case PrimitiveType.Fixed64: - case PrimitiveType.Sfixed32: - case PrimitiveType.Sfixed64: - case PrimitiveType.Float: - case PrimitiveType.Double: - case PrimitiveType.String: - case PrimitiveType.EntityId: - case PrimitiveType.Bytes: - return "TextField"; - case PrimitiveType.Bool: - return "Toggle"; - case PrimitiveType.Entity: - return ""; - case PrimitiveType.Invalid: - throw new ArgumentException("Unknown primitive type encountered."); - default: - throw new ArgumentOutOfRangeException(); - } - case ValueType.Type: - return ""; - default: - throw new ArgumentOutOfRangeException(); - } - } } } diff --git a/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/FieldTypeHandler.cs b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/FieldTypeHandler.cs new file mode 100644 index 0000000000..73a4d36838 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/FieldTypeHandler.cs @@ -0,0 +1,200 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Improbable.Gdk.CodeGeneration.Model; +using Improbable.Gdk.CodeGeneration.Model.Details; +using Improbable.Gdk.CodeGeneration.Utils; +using ValueType = Improbable.Gdk.CodeGeneration.Model.ValueType; + +namespace Improbable.Gdk.CodeGenerator +{ + public class FieldTypeHandler + { + private readonly DetailsStore detailsStore; + + public FieldTypeHandler(DetailsStore detailsStore) + { + this.detailsStore = detailsStore; + } + + public string ToFieldDeclaration(UnityFieldDetails fieldDetails) + { + switch (fieldDetails.FieldType) + { + case SingularFieldType singularFieldType: + var uiType = GetUiFieldType(singularFieldType.ContainedType); + + if (uiType == "") + { + // TODO: Eliminate this case by supporting 'Entity'. + return ""; + } + + return $"private readonly {uiType} {fieldDetails.CamelCaseName}Field;"; + default: + // TODO: Lists, maps, and options + return ""; + } + } + + public IEnumerable ToFieldInitialisation(UnityFieldDetails fieldDetails, string parentContainer) + { + switch (fieldDetails.FieldType) + { + case SingularFieldType singularFieldType: + + var uiType = GetUiFieldType(singularFieldType.ContainedType); + + if (uiType == "") + { + // TODO: Eliminate this case by supporting 'Entity'. + yield break; + } + + var humanReadableName = Formatting.SnakeCaseToHumanReadable(fieldDetails.Name); + yield return $"{fieldDetails.CamelCaseName}Field = new {uiType}(\"{humanReadableName}\");"; + + if (singularFieldType.ContainedType.Category != ValueType.Type) + { + yield return $"{fieldDetails.CamelCaseName}Field.SetEnabled(false);"; + } + + if (singularFieldType.ContainedType.Category == ValueType.Enum) + { + yield return $"{fieldDetails.CamelCaseName}Field.Init(default({fieldDetails.Type}));"; + } + + yield return $"{parentContainer}.Add({fieldDetails.CamelCaseName}Field);"; + break; + default: + // TODO: Lists, maps, and options + yield break; + } + } + + public string ToUiFieldUpdate(UnityFieldDetails fieldDetails, string fieldParent) + { + var uiElementName = $"{fieldDetails.CamelCaseName}Field"; + switch (fieldDetails.FieldType) + { + case SingularFieldType singularFieldType: + switch (singularFieldType.ContainedType.Category) + { + case ValueType.Enum: + return $"{uiElementName}.value = {fieldParent}.{fieldDetails.PascalCaseName};"; + case ValueType.Primitive: + var primitiveType = singularFieldType.ContainedType.PrimitiveType.Value; + + switch (primitiveType) + { + case PrimitiveType.Int32: + case PrimitiveType.Int64: + case PrimitiveType.Uint32: + case PrimitiveType.Uint64: + case PrimitiveType.Sint32: + case PrimitiveType.Sint64: + case PrimitiveType.Fixed32: + case PrimitiveType.Fixed64: + case PrimitiveType.Sfixed32: + case PrimitiveType.Sfixed64: + case PrimitiveType.Float: + case PrimitiveType.Double: + case PrimitiveType.String: + case PrimitiveType.EntityId: + return $"{uiElementName}.value = {fieldParent}.{fieldDetails.PascalCaseName}.ToString();"; + case PrimitiveType.Bytes: + return $"{uiElementName}.value = global::System.Text.Encoding.Default.GetString({fieldParent}.{fieldDetails.PascalCaseName});"; + case PrimitiveType.Bool: + return $"{uiElementName}.value = {fieldParent}.{fieldDetails.PascalCaseName};"; + break; + case PrimitiveType.Entity: + // TODO: Entity type. + return ""; + case PrimitiveType.Invalid: + throw new ArgumentException("Unknown primitive type encountered"); + default: + throw new ArgumentOutOfRangeException(); + } + case ValueType.Type: + return $"{uiElementName}.Update({fieldParent}.{fieldDetails.PascalCaseName});"; + default: + throw new ArgumentOutOfRangeException(); + } + default: + // TODO: Lists, maps, and options + return ""; + } + } + + private string GetUiFieldType(ContainedType type) + { + switch (type.Category) + { + case ValueType.Enum: + return "EnumField"; + case ValueType.Primitive: + switch (type.PrimitiveType.Value) + { + case PrimitiveType.Int32: + case PrimitiveType.Int64: + case PrimitiveType.Uint32: + case PrimitiveType.Uint64: + case PrimitiveType.Sint32: + case PrimitiveType.Sint64: + case PrimitiveType.Fixed32: + case PrimitiveType.Fixed64: + case PrimitiveType.Sfixed32: + case PrimitiveType.Sfixed64: + case PrimitiveType.Float: + case PrimitiveType.Double: + case PrimitiveType.String: + case PrimitiveType.EntityId: + case PrimitiveType.Bytes: + return "TextField"; + case PrimitiveType.Bool: + return "Toggle"; + case PrimitiveType.Entity: + return ""; + case PrimitiveType.Invalid: + throw new ArgumentException("Unknown primitive type encountered."); + default: + throw new ArgumentOutOfRangeException(); + } + case ValueType.Type: + return CalculateRendererFullyQualifiedName(type); + default: + throw new ArgumentOutOfRangeException(); + } + } + + // We generate child types inside the parent type (if we don't there will be clashes). + // However this means to get the renderer type we can't just grab the FQN, since each intermediate type will + // have 'Renderer' appended to it. + // + // We need to crawl back up the type tree until we find the most-parent type and construct the FQN from + // this information. + // i.e. - global::{namespace of parent type}.{parent type}Renderer.{child type}Renderer.{child type}Renderer + private string CalculateRendererFullyQualifiedName(ContainedType type) + { + var typeDetails = detailsStore.Types[type.RawType]; + + var rendererChain = new List(); + + while (true) + { + rendererChain.Add($"{typeDetails.Name}Renderer"); + if (typeDetails.Parent == null) + { + break; + } + + typeDetails = typeDetails.Parent; + } + + rendererChain.Reverse(); + + return $"global::{typeDetails.Namespace}.{string.Join(".", rendererChain)}"; + } + } +} + From b7dd628e42ed0f787c5395f9d7105dccfc639af7 Mon Sep 17 00:00:00 2001 From: Jamie Brynes Date: Wed, 10 Jun 2020 12:01:28 +0100 Subject: [PATCH 3/6] add base class for generated schema type renderers --- .../Codegen/SchemaTypeVisualElement.cs | 22 +++++++++++++++++++ .../Codegen/SchemaTypeVisualElement.cs.meta | 3 +++ 2 files changed, 25 insertions(+) create mode 100644 workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs create mode 100644 workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs.meta diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs new file mode 100644 index 0000000000..122df0c00e --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs @@ -0,0 +1,22 @@ +using UnityEngine.UIElements; + +namespace Improbable.Gdk.Debug.WorkerInspector.Codegen +{ + public abstract class SchemaTypeVisualElement : VisualElement + { + protected readonly VisualElement Container; + + protected SchemaTypeVisualElement(string label) + { + AddToClassList("user-defined-type-container"); + + Add(new Label(label)); + + Container = new VisualElement(); + Container.AddToClassList("user-defined-type-container-data"); + Add(Container); + } + + public abstract void Update(T data); + } +} diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs.meta b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs.meta new file mode 100644 index 0000000000..4d8b05f0e2 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Codegen/SchemaTypeVisualElement.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ae643d89cec94406bfb873080d4f44e4 +timeCreated: 1591785133 \ No newline at end of file From abe35616e0910ab05953abefad018e7278f07656 Mon Sep 17 00:00:00 2001 From: Jamie Brynes Date: Wed, 10 Jun 2020 12:02:05 +0100 Subject: [PATCH 4/6] generate types --- .../Source/ComponentVisualElementJob.cs | 19 ++++- .../TypeVisualElementGenerator.cs | 70 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/TypeVisualElementGenerator.cs diff --git a/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/ComponentVisualElementJob.cs b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/ComponentVisualElementJob.cs index b1c4fc1bef..9ade5cc1e9 100644 --- a/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/ComponentVisualElementJob.cs +++ b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/ComponentVisualElementJob.cs @@ -20,8 +20,25 @@ public ComponentVisualElementJob(CodegenJobOptions options, IFileSystem fileSyst AddJobTarget(Path.Combine(relativeOutputPath, DebugAsmdefFileName), () => DebugAssemblyGenerator.Generate()); var componentsToGenerate = detailsStore.Components.Values.ToList(); - AddGenerators(relativeOutputPath, componentsToGenerate, component => ($"{component.Name}Renderer.cs", ComponentVisualElementGenerator.Generate)); + var componentGenerator = new ComponentVisualElementGenerator(detailsStore); + AddGenerators(relativeOutputPath, componentsToGenerate, component => ($"{component.Name}Renderer.cs", componentGenerator.Generate)); Logger.Trace($"Added job targets for {componentsToGenerate.Count} components"); + + // Types + Logger.Trace("Gathering nested types."); + var allNestedTypes = detailsStore.Types + .SelectMany(kv => detailsStore.GetNestedTypes(kv.Key)) + .ToHashSet(); + + Logger.Trace("Gathering types details."); + var typesToGenerate = detailsStore.Types + .Where(kv => !allNestedTypes.Contains(kv.Key)) + .Select(kv => kv.Value) + .ToList(); + + var typeGenerator = new TypeVisualElementGenerator(detailsStore); + AddGenerators(relativeOutputPath, typesToGenerate, type => ($"{type.Name}Renderer.cs", typeGenerator.Generate)); + Logger.Trace($"Added job targets for {typesToGenerate.Count} types"); } } } diff --git a/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/TypeVisualElementGenerator.cs b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/TypeVisualElementGenerator.cs new file mode 100644 index 0000000000..084825ad61 --- /dev/null +++ b/workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/Generators/DebugExtensions/TypeVisualElementGenerator.cs @@ -0,0 +1,70 @@ +using System.Linq; +using Improbable.Gdk.CodeGeneration.CodeWriter; +using Improbable.Gdk.CodeGeneration.CodeWriter.Scopes; +using Improbable.Gdk.CodeGeneration.Model.Details; + +namespace Improbable.Gdk.CodeGenerator +{ + public class TypeVisualElementGenerator + { + private readonly FieldTypeHandler fieldTypeHandler; + + public TypeVisualElementGenerator(DetailsStore detailsStore) + { + fieldTypeHandler = new FieldTypeHandler(detailsStore); + } + + public CodeWriter Generate(UnityTypeDetails details) + { + return CodeWriter.Populate(cgw => + { + cgw.UsingDirectives( + "UnityEngine.UIElements", + "UnityEditor.UIElements", + "Improbable.Gdk.Debug.WorkerInspector.Codegen" + ); + + cgw.Namespace(details.Namespace, ns => + { + ns.Type(GenerateType(details)); + }); + }); + } + + private TypeBlock GenerateType(UnityTypeDetails details) + { + return Scope.Type($"public class {details.Name}Renderer : SchemaTypeVisualElement<{details.FullyQualifiedName}>", + type => + { + type.TextList(details.FieldDetails.Select(fieldTypeHandler.ToFieldDeclaration)); + + GenerateConstructor(type, details); + GenerateUpdateMethod(type, details); + + foreach (var nestedType in details.ChildTypes) + { + type.Type(GenerateType(nestedType)); + } + }); + } + + private void GenerateConstructor(TypeBlock typeBlock, UnityTypeDetails details) + { + typeBlock.Method($"public {details.Name}Renderer(string label) : base(label)", mb => + { + foreach (var field in details.FieldDetails) + { + mb.TextList(fieldTypeHandler.ToFieldInitialisation(field, "Container")); + } + }); + } + + private void GenerateUpdateMethod(TypeBlock typeBlock, UnityTypeDetails details) + { + typeBlock.Method($"public override void Update({details.FullyQualifiedName} data)", mb => + { + mb.TextList(details.FieldDetails.Select(fd => fieldTypeHandler.ToUiFieldUpdate(fd, "data"))); + }); + } + } +} From ab3287dcdfff7e208423b8e14064a675be5eba95 Mon Sep 17 00:00:00 2001 From: Jamie Brynes Date: Wed, 10 Jun 2020 12:02:21 +0100 Subject: [PATCH 5/6] add styling & fix up gray-ed out text in the inspector --- .../Templates/WorkerInspectorWindow.uss | 16 ++++++++++++++++ .../Templates/WorkerInspectorWindow_Dark.uss | 10 +++++++++- .../Templates/WorkerInspectorWindow_Light.uss | 10 +++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss index ab0c5698fc..d27acbe410 100644 --- a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow.uss @@ -132,3 +132,19 @@ flex-grow: 1; max-width: 50%; } + +.user-defined-type-container { + margin: 1px 0px 1px 3px; +} + +.user-defined-type-container-data { + margin-left: 8px; +} + +.component-foldout .unity-text-field:disabled, .unity-toggle:disabled { + opacity: 1; +} + +#worker-details .unity-text-field:disabled, .unity-toggle:disabled { + opacity: 1; +} diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss index 40af681017..67855b38b1 100644 --- a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Dark.uss @@ -1,4 +1,8 @@ -.is-auth-toggle .unity-label:disabled { +#worker-details .unity-label:disabled { + color: white; +} + +.component-foldout .unity-label:disabled { color: white; } @@ -9,3 +13,7 @@ #worker-flags .unity-label:disabled { color: white; } + +.unity-label { + color: white; +} diff --git a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss index 1d3fcf74db..4e9fe7b30a 100644 --- a/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss +++ b/workers/unity/Packages/io.improbable.gdk.debug/WorkerInspector/Templates/WorkerInspectorWindow_Light.uss @@ -1,4 +1,8 @@ -.is-auth-toggle .unity-label:disabled { +#worker-details .unity-label:disabled { + color: black; +} + +.component-foldout .unity-label:disabled { color: black; } @@ -9,3 +13,7 @@ #worker-flags .unity-label:disabled { color: black; } + +.unity-label { + color: black; +} From 6131a58e74136ea05632060eb696247cf4ecd35b Mon Sep 17 00:00:00 2001 From: Jamie Brynes Date: Wed, 10 Jun 2020 17:56:22 +0100 Subject: [PATCH 6/6] force BK build