Skip to content
This repository was archived by the owner on Jan 18, 2022. It is now read-only.

Commit d60046b

Browse files
author
Jamie Brynes
authored
Add rendering support for user-defined types (#1391)
1 parent 8330867 commit d60046b

File tree

11 files changed

+372
-161
lines changed

11 files changed

+372
-161
lines changed

workers/unity/Packages/io.improbable.gdk.debug/.codegen/Source/ComponentVisualElementJob.cs

+18-1
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,25 @@ public ComponentVisualElementJob(CodegenJobOptions options, IFileSystem fileSyst
2020
AddJobTarget(Path.Combine(relativeOutputPath, DebugAsmdefFileName), () => DebugAssemblyGenerator.Generate());
2121

2222
var componentsToGenerate = detailsStore.Components.Values.ToList();
23-
AddGenerators(relativeOutputPath, componentsToGenerate, component => ($"{component.Name}Renderer.cs", ComponentVisualElementGenerator.Generate));
23+
var componentGenerator = new ComponentVisualElementGenerator(detailsStore);
24+
AddGenerators(relativeOutputPath, componentsToGenerate, component => ($"{component.Name}Renderer.cs", componentGenerator.Generate));
2425
Logger.Trace($"Added job targets for {componentsToGenerate.Count} components");
26+
27+
// Types
28+
Logger.Trace("Gathering nested types.");
29+
var allNestedTypes = detailsStore.Types
30+
.SelectMany(kv => detailsStore.GetNestedTypes(kv.Key))
31+
.ToHashSet();
32+
33+
Logger.Trace("Gathering types details.");
34+
var typesToGenerate = detailsStore.Types
35+
.Where(kv => !allNestedTypes.Contains(kv.Key))
36+
.Select(kv => kv.Value)
37+
.ToList();
38+
39+
var typeGenerator = new TypeVisualElementGenerator(detailsStore);
40+
AddGenerators(relativeOutputPath, typesToGenerate, type => ($"{type.Name}Renderer.cs", typeGenerator.Generate));
41+
Logger.Trace($"Added job targets for {typesToGenerate.Count} types");
2542
}
2643
}
2744
}
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
using System;
2-
using System.Collections.Generic;
31
using System.Linq;
42
using Improbable.Gdk.CodeGeneration.CodeWriter;
53
using Improbable.Gdk.CodeGeneration.CodeWriter.Scopes;
6-
using Improbable.Gdk.CodeGeneration.Model;
74
using Improbable.Gdk.CodeGeneration.Model.Details;
8-
using Improbable.Gdk.CodeGeneration.Utils;
9-
using ValueType = Improbable.Gdk.CodeGeneration.Model.ValueType;
105

116
namespace Improbable.Gdk.CodeGenerator
127
{
13-
public static class ComponentVisualElementGenerator
8+
public class ComponentVisualElementGenerator
149
{
15-
public static CodeWriter Generate(UnityComponentDetails details)
10+
private readonly FieldTypeHandler typeGenerator;
11+
12+
public ComponentVisualElementGenerator(DetailsStore detailsStore)
13+
{
14+
typeGenerator = new FieldTypeHandler(detailsStore);
15+
}
16+
17+
public CodeWriter Generate(UnityComponentDetails details)
1618
{
1719
return CodeWriter.Populate(cgw =>
1820
{
@@ -29,7 +31,7 @@ public static CodeWriter Generate(UnityComponentDetails details)
2931
{
3032
type.Line($"public override ComponentType ComponentType {{ get; }} = ComponentType.ReadOnly<{details.Name}.Component>();");
3133

32-
type.TextList(details.FieldDetails.Select(ToFieldDeclaration));
34+
type.TextList(details.FieldDetails.Select(typeGenerator.ToFieldDeclaration));
3335

3436
GenerateConstructor(type, details);
3537
GenerateUpdateMethod(type, details);
@@ -38,27 +40,7 @@ public static CodeWriter Generate(UnityComponentDetails details)
3840
});
3941
}
4042

41-
private static string ToFieldDeclaration(UnityFieldDetails fieldDetails)
42-
{
43-
switch (fieldDetails.FieldType)
44-
{
45-
case SingularFieldType singularFieldType:
46-
var uiType = GetUiFieldType(singularFieldType.ContainedType);
47-
48-
if (uiType == "")
49-
{
50-
// TODO: Eliminate this case.
51-
return "";
52-
}
53-
54-
return $"private readonly {uiType} {fieldDetails.CamelCaseName}Field;";
55-
default:
56-
// TODO: Lists, maps, and options
57-
return "";
58-
}
59-
}
60-
61-
private static void GenerateConstructor(TypeBlock typeBlock, UnityComponentDetails details)
43+
private void GenerateConstructor(TypeBlock typeBlock, UnityComponentDetails details)
6244
{
6345
typeBlock.Method($"public {details.Name}Renderer() : base()", mb =>
6446
{
@@ -67,146 +49,20 @@ private static void GenerateConstructor(TypeBlock typeBlock, UnityComponentDetai
6749

6850
foreach (var field in details.FieldDetails)
6951
{
70-
mb.TextList(ToFieldInitialisation(field));
52+
mb.TextList(typeGenerator.ToFieldInitialisation(field, "ComponentFoldout"));
7153
}
7254
});
7355
}
7456

75-
private static IEnumerable<string> ToFieldInitialisation(UnityFieldDetails fieldDetails)
76-
{
77-
switch (fieldDetails.FieldType)
78-
{
79-
case SingularFieldType singularFieldType:
80-
81-
var uiType = GetUiFieldType(singularFieldType.ContainedType);
82-
83-
if (uiType == "")
84-
{
85-
// TODO: Eliminate this case.
86-
yield break;
87-
}
88-
89-
var humanReadableName = Formatting.SnakeCaseToHumanReadable(fieldDetails.Name);
90-
yield return $"{fieldDetails.CamelCaseName}Field = new {uiType}(\"{humanReadableName}\");";
91-
yield return $"{fieldDetails.CamelCaseName}Field.SetEnabled(false);";
92-
93-
if (singularFieldType.ContainedType.Category == ValueType.Enum)
94-
{
95-
yield return $"{fieldDetails.CamelCaseName}Field.Init(default({fieldDetails.Type}));";
96-
}
97-
98-
yield return $"ComponentFoldout.Add({fieldDetails.CamelCaseName}Field);";
99-
break;
100-
default:
101-
// TODO: Lists, maps, and options
102-
yield break;
103-
}
104-
}
105-
106-
private static void GenerateUpdateMethod(TypeBlock typeBlock, UnityComponentDetails details)
57+
private void GenerateUpdateMethod(TypeBlock typeBlock, UnityComponentDetails details)
10758
{
10859
typeBlock.Method("public override void Update(EntityManager manager, Entity entity)", mb =>
10960
{
11061
mb.Line($"AuthoritativeToggle.value = manager.HasComponent<{details.Name}.HasAuthority>(entity);");
11162
mb.Line($"var component = manager.GetComponentData<{details.Name}.Component>(entity);");
11263

113-
mb.TextList(TextList.New(details.FieldDetails.Select(ToUiFieldUpdate)));
64+
mb.TextList(details.FieldDetails.Select(fd => typeGenerator.ToUiFieldUpdate(fd, "component")));
11465
});
11566
}
116-
117-
private static string ToUiFieldUpdate(UnityFieldDetails fieldDetails)
118-
{
119-
switch (fieldDetails.FieldType)
120-
{
121-
case SingularFieldType singularFieldType:
122-
switch (singularFieldType.ContainedType.Category)
123-
{
124-
case ValueType.Enum:
125-
return $"{fieldDetails.CamelCaseName}Field.value = component.{fieldDetails.PascalCaseName};";
126-
case ValueType.Primitive:
127-
var primitiveType = singularFieldType.ContainedType.PrimitiveType.Value;
128-
129-
switch (primitiveType)
130-
{
131-
case PrimitiveType.Int32:
132-
case PrimitiveType.Int64:
133-
case PrimitiveType.Uint32:
134-
case PrimitiveType.Uint64:
135-
case PrimitiveType.Sint32:
136-
case PrimitiveType.Sint64:
137-
case PrimitiveType.Fixed32:
138-
case PrimitiveType.Fixed64:
139-
case PrimitiveType.Sfixed32:
140-
case PrimitiveType.Sfixed64:
141-
case PrimitiveType.Float:
142-
case PrimitiveType.Double:
143-
case PrimitiveType.String:
144-
case PrimitiveType.EntityId:
145-
return $"{fieldDetails.CamelCaseName}Field.value = component.{fieldDetails.PascalCaseName}.ToString();";
146-
case PrimitiveType.Bytes:
147-
return $"{fieldDetails.CamelCaseName}Field.value = global::System.Text.Encoding.Default.GetString(component.{fieldDetails.PascalCaseName});";
148-
case PrimitiveType.Bool:
149-
return $"{fieldDetails.CamelCaseName}Field.value = component.{fieldDetails.PascalCaseName};";
150-
break;
151-
case PrimitiveType.Entity:
152-
// TODO: Entity type.
153-
return "";
154-
case PrimitiveType.Invalid:
155-
throw new ArgumentException("Unknown primitive type encountered");
156-
default:
157-
throw new ArgumentOutOfRangeException();
158-
}
159-
case ValueType.Type:
160-
// TODO: User defined types.
161-
return "";
162-
default:
163-
throw new ArgumentOutOfRangeException();
164-
}
165-
default:
166-
// TODO: Lists, maps, and options
167-
return "";
168-
}
169-
}
170-
171-
private static string GetUiFieldType(ContainedType type)
172-
{
173-
switch (type.Category)
174-
{
175-
case ValueType.Enum:
176-
return "EnumField";
177-
case ValueType.Primitive:
178-
switch (type.PrimitiveType.Value)
179-
{
180-
case PrimitiveType.Int32:
181-
case PrimitiveType.Int64:
182-
case PrimitiveType.Uint32:
183-
case PrimitiveType.Uint64:
184-
case PrimitiveType.Sint32:
185-
case PrimitiveType.Sint64:
186-
case PrimitiveType.Fixed32:
187-
case PrimitiveType.Fixed64:
188-
case PrimitiveType.Sfixed32:
189-
case PrimitiveType.Sfixed64:
190-
case PrimitiveType.Float:
191-
case PrimitiveType.Double:
192-
case PrimitiveType.String:
193-
case PrimitiveType.EntityId:
194-
case PrimitiveType.Bytes:
195-
return "TextField";
196-
case PrimitiveType.Bool:
197-
return "Toggle";
198-
case PrimitiveType.Entity:
199-
return "";
200-
case PrimitiveType.Invalid:
201-
throw new ArgumentException("Unknown primitive type encountered.");
202-
default:
203-
throw new ArgumentOutOfRangeException();
204-
}
205-
case ValueType.Type:
206-
return "";
207-
default:
208-
throw new ArgumentOutOfRangeException();
209-
}
210-
}
21167
}
21268
}

0 commit comments

Comments
 (0)