luban/src/Luban.Job.Common/Source/Defs/DefBeanBase.cs

171 lines
5.0 KiB
C#

using Luban.Job.Common.RawDefs;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Luban.Job.Common.Defs
{
public abstract class DefBeanBase : DefTypeBase
{
public bool IsBean => true;
public string Parent { get; }
public bool IsValueType { get; }
public DefBeanBase ParentDefType { get; protected set; }
public DefBeanBase RootDefType => this.ParentDefType == null ? this : this.ParentDefType.RootDefType;
public bool IsSerializeCompatible { get; }
public List<DefBeanBase> Children { get; set; }
public List<DefBeanBase> HierarchyNotAbstractChildren { get; set; }
public bool IsNotAbstractType => Children == null;
public bool IsAbstractType => Children != null;
public List<DefFieldBase> HierarchyFields { get; private set; } = new List<DefFieldBase>();
public List<DefFieldBase> Fields { get; } = new List<DefFieldBase>();
public string CsClassModifier => IsAbstractType ? "abstract" : "sealed";
public string CsMethodModifier => ParentDefType != null ? "override" : (IsAbstractType ? "virtual" : "");
public string JavaClassModifier => IsAbstractType ? "abstract" : "final";
public string JavaMethodModifier => ParentDefType != null ? "override" : (IsAbstractType ? "virtual" : "");
public DefBeanBase(Bean b)
{
Name = b.Name;
Namespace = b.Namespace;
Parent = b.Parent;
Id = b.TypeId;
IsValueType = b.IsValueType;
foreach (var field in b.Fields)
{
Fields.Add(CreateField(field, 0));
}
}
protected abstract DefFieldBase CreateField(Field f, int idOffset);
public void CollectHierarchyNotAbstractChildren(List<DefBeanBase> children)
{
if (IsAbstractType)
{
foreach (var c in Children)
{
c.CollectHierarchyNotAbstractChildren(children);
}
}
else
{
children.Add(this);
}
}
public virtual DefBeanBase GetNotAbstractChildType(string typeNameOrAliasName)
{
if (string.IsNullOrWhiteSpace(typeNameOrAliasName))
{
return null;
}
foreach (var c in HierarchyNotAbstractChildren)
{
if (c.Name == typeNameOrAliasName)
{
return c;
}
}
return null;
}
internal DefFieldBase GetField(string index)
{
return HierarchyFields.Where(f => f.Name == index).FirstOrDefault();
}
public bool TryGetField(string index, out DefFieldBase field, out int fieldIndexId)
{
for (int i = 0; i < HierarchyFields.Count; i++)
{
if (HierarchyFields[i].Name == index)
{
field = HierarchyFields[i];
fieldIndexId = i;
return true;
}
}
field = null;
fieldIndexId = 0;
return false;
}
protected void CollectHierarchyFields(List<DefFieldBase> fields)
{
if (ParentDefType != null)
{
ParentDefType.CollectHierarchyFields(fields);
}
fields.AddRange(Fields);
}
public override void PreCompile()
{
if (!string.IsNullOrEmpty(Parent))
{
if ((ParentDefType = (DefBeanBase)AssemblyBase.GetDefType(Namespace, Parent)) == null)
{
throw new Exception($"bean:{FullName} parent:{Parent} not exist");
}
if (ParentDefType.Children == null)
{
ParentDefType.Children = new List<DefBeanBase>();
}
ParentDefType.Children.Add(this);
}
CollectHierarchyFields(HierarchyFields);
}
public override void Compile()
{
var cs = new List<DefBeanBase>();
if (Children != null)
{
CollectHierarchyNotAbstractChildren(cs);
}
HierarchyNotAbstractChildren = cs;
var ids = new HashSet<int>();
foreach (var c in cs)
{
if (c.Id <= 0)
{
throw new Exception($"bean:{FullName} is child of dynamic type. beanid:{Id} can't less then 0!");
}
if (!ids.Add(c.Id))
{
throw new Exception($"bean:{c.FullName} beanid:{c.Id} duplicate!");
}
}
DefFieldBase.CompileFields(this, HierarchyFields, IsSerializeCompatible);
}
public override void PostCompile()
{
foreach (var field in HierarchyFields)
{
field.PostCompile();
}
}
}
}