TechbloxModdingAPI/CodeGenerator/ECSAnalyzer.cs
NorbiPeti 9be1b5fdaf
Implemented improved ECS class generator based on entity descriptors
I can't test it yet because the API is full of errors because of the refactoring
2023-10-04 02:36:25 +02:00

65 lines
No EOL
2.5 KiB
C#

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Gamecraft.Tweaks;
using Svelto.ECS;
namespace CodeGenerator
{
public class ECSAnalyzer
{
public static ECSClassInfo AnalyzeEntityDescriptor(Type entityDescriptorType)
{
// TODO: Add support for creating/deleting entities (getting an up to date server/client engines root)
var templateType = typeof(EntityDescriptorTemplate<>).MakeGenericType(entityDescriptorType);
var getTemplateClass = Expression.Constant(templateType);
var getDescriptorExpr = Expression.PropertyOrField(getTemplateClass, "descriptor");
var getTemplateDescriptorExpr =
Expression.Lambda<Func<IEntityDescriptor>>(getDescriptorExpr);
var getTemplateDescriptor = getTemplateDescriptorExpr.Compile();
var builders = getTemplateDescriptor().componentsToBuild;
return new ECSClassInfo
{
Name = entityDescriptorType.Name.Replace("EntityComponent", "").Replace("EntityStruct", ""),
Properties = builders.Select(builder => builder.GetEntityComponentType()).SelectMany(AnalyzeFields).ToArray()
};
}
private static ECSPropertyInfo[] AnalyzeFields(Type componentType)
{
bool useReflection = componentType.IsNotPublic;
var result = new List<ECSPropertyInfo>();
foreach (var field in componentType.GetFields())
{
var attr = field.GetCustomAttribute<TweakableStatAttribute>();
string propName = field.Name;
if (attr != null)
propName = attr.propertyName;
propName = char.ToUpper(propName[0]) + propName[1..];
if (useReflection)
{
result.Add(new ECSReflectedPropertyInfo
{
Name = propName,
Type = field.FieldType,
OriginalClassName = componentType.FullName,
ComponentType = componentType
});
}
result.Add(new ECSPropertyInfo
{
Name = propName,
Type = field.FieldType,
ComponentType = componentType
});
}
return result.ToArray();
}
}
}