Entitas  0.35.0
Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
CodeGenerator.cs
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 
6 namespace Entitas.CodeGenerator {
7 
8  public static class CodeGenerator {
9 
10  public const string DEFAULT_POOL_NAME = "Pool";
11  public const string COMPONENT_SUFFIX = "Component";
12 
13  public const string DEFAULT_COMPONENT_LOOKUP_TAG = "ComponentIds";
14  public const string AUTO_GENERATED_HEADER_FORMAT = @"//------------------------------------------------------------------------------
15 // <auto-generated>
16 // This code was generated by {0}.
17 //
18 // Changes to this file may cause incorrect behavior and will be lost if
19 // the code is regenerated.
20 // </auto-generated>
21 //------------------------------------------------------------------------------
22 ";
23 
24  public static CodeGenFile[] Generate(ICodeGeneratorDataProvider provider, string directory, ICodeGenerator[] codeGenerators) {
25  directory = GetSafeDir(directory);
26  CleanDir(directory);
27 
28  var generatedFiles = new List<CodeGenFile>();
29  var componentInfos = provider.componentInfos;
30 
31  foreach(var generator in codeGenerators.OfType<IPoolCodeGenerator>()) {
32  var files = generator.Generate(provider.poolNames);
33  generatedFiles.AddRange(files);
34  writeFiles(directory, files);
35  }
36 
37  foreach(var generator in codeGenerators.OfType<IComponentCodeGenerator>()) {
38  var files = generator.Generate(componentInfos);
39  generatedFiles.AddRange(files);
40  writeFiles(directory, files);
41  }
42 
43  foreach(var generator in codeGenerators.OfType<IBlueprintsCodeGenerator>()) {
44  var files = generator.Generate(provider.blueprintNames);
45  generatedFiles.AddRange(files);
46  writeFiles(directory, files);
47  }
48 
49  return generatedFiles.ToArray();
50  }
51 
52  public static string GetSafeDir(string directory) {
53  if(!directory.EndsWith("/", StringComparison.Ordinal)) {
54  directory += "/";
55  }
56  if(!directory.EndsWith("Generated/", StringComparison.Ordinal)) {
57  directory += "Generated/";
58  }
59  return directory;
60  }
61 
62  public static void CleanDir(string directory) {
63  directory = GetSafeDir(directory);
64  if(Directory.Exists(directory)) {
65  var files = new DirectoryInfo(directory).GetFiles("*.cs", SearchOption.AllDirectories);
66  foreach(var file in files) {
67  try {
68  File.Delete(file.FullName);
69  } catch {
70  Console.WriteLine("Could not delete file " + file);
71  }
72  }
73  } else {
74  Directory.CreateDirectory(directory);
75  }
76  }
77 
78  static void writeFiles(string directory, CodeGenFile[] files) {
79  if(!Directory.Exists(directory)) {
80  Directory.CreateDirectory(directory);
81  }
82  foreach(var file in files) {
83  var fileName = directory + file.fileName + ".cs";
84  var fileContent = file.fileContent.Replace("\n", Environment.NewLine);
85  var header = string.Format(AUTO_GENERATED_HEADER_FORMAT, file.generatorName);
86  File.WriteAllText(fileName, header + fileContent);
87  }
88  }
89  }
90 
91  public static class CodeGeneratorExtensions {
92 
93  public static bool IsDefaultPoolName(this string poolName) {
94  return poolName == CodeGenerator.DEFAULT_POOL_NAME;
95  }
96 
97  public static string PoolPrefix(this string poolName) {
98  return poolName.IsDefaultPoolName() ? string.Empty : poolName;
99  }
100 
101  public static string[] ComponentLookupTags(this ComponentInfo componentInfo) {
102  return componentInfo.pools
103  .Select(poolName => poolName.PoolPrefix() + CodeGenerator.DEFAULT_COMPONENT_LOOKUP_TAG)
104  .ToArray();
105  }
106 
107  public static string UppercaseFirst(this string str) {
108  return char.ToUpper(str[0]) + str.Substring(1);
109  }
110 
111  public static string LowercaseFirst(this string str) {
112  return char.ToLower(str[0]) + str.Substring(1);
113  }
114 
115  public static string ToUnixLineEndings(this string str) {
116  return str.Replace("\r\n", "\n").Replace("\r", "\n");
117  }
118  }
119 }