|
- using System.CodeDom;
- using System.CodeDom.Compiler;
- using System.IO;
- using System.Linq;
- using RobocraftX.Common;
- using Svelto.ECS;
- using Techblox.EngineBlock;
-
- namespace CodeGenerator
- {
- public class BlockClassGenerator
- {
- public void Generate(string name, string group)
- {
- if (group is null)
- {
- group = GetGroup(name) + "_BLOCK_GROUP";
- if (typeof(CommonExclusiveGroups).GetFields().All(field => field.Name != group))
- group = GetGroup(name) + "_BLOCK_BUILD_GROUP";
- }
-
- var codeUnit = new CodeCompileUnit();
- var ns = new CodeNamespace("TechbloxModdingAPI.Blocks");
- ns.Imports.Add(new CodeNamespaceImport("RobocraftX.Common"));
- ns.Imports.Add(new CodeNamespaceImport("Svelto.ECS"));
- var cl = new CodeTypeDeclaration(name);
- cl.BaseTypes.Add(new CodeTypeReference("Block"));
- cl.Members.Add(new CodeConstructor
- {
- Parameters = {new CodeParameterDeclarationExpression("EGID", "egid")},
- Comments = {new CodeCommentStatement($"{name} constructor", true)},
- BaseConstructorArgs = {new CodeVariableReferenceExpression("egid")}
- });
- cl.Members.Add(new CodeConstructor
- {
- Parameters =
- {
- new CodeParameterDeclarationExpression(typeof(uint), "id")
- },
- Comments = {new CodeCommentStatement($"{name} constructor", true)},
- BaseConstructorArgs =
- {
- new CodeObjectCreateExpression("EGID", new CodeVariableReferenceExpression("id"),
- new CodeFieldReferenceExpression(new CodeTypeReferenceExpression("CommonExclusiveGroups"),
- group))
- }
- });
- GenerateProperties<EngineBlockComponent>(cl);
- ns.Types.Add(cl);
- codeUnit.Namespaces.Add(ns);
-
- var provider = CodeDomProvider.CreateProvider("CSharp");
- using (var sw = new StreamWriter($"{name}.cs"))
- {
- provider.GenerateCodeFromCompileUnit(codeUnit, sw, new CodeGeneratorOptions {BracingStyle = "C"});
- }
- }
-
- private static string GetGroup(string name)
- {
- var ret = "";
- foreach (var ch in name)
- {
- if (char.IsUpper(ch) && ret.Length > 0)
- ret += "_" + ch;
- else
- ret += char.ToUpper(ch);
- }
-
- return ret;
- }
-
- private void GenerateProperties<T>(CodeTypeDeclaration cl) where T : IEntityComponent
- {
- var type = typeof(T);
- foreach (var field in type.GetFields())
- {
- var propName = char.ToUpper(field.Name[0]) + field.Name.Substring(1);
- var structFieldReference = new CodeFieldReferenceExpression(new CodeMethodInvokeExpression(
- new CodeMethodReferenceExpression(new CodeSnippetExpression("BlockEngine"),
- "GetBlockInfo", new CodeTypeReference(type)),
- new CodeThisReferenceExpression()), field.Name);
- cl.Members.Add(new CodeMemberProperty
- {
- Name = propName,
- HasGet = true,
- HasSet = true,
- GetStatements =
- {
- new CodeMethodReturnStatement(structFieldReference)
- },
- SetStatements =
- {
- new CodeAssignStatement(structFieldReference, new CodePropertySetValueReferenceExpression())
- },
- Type = new CodeTypeReference(field.FieldType)
- });
- }
- }
- }
- }
|