【调整】调整externaltype实现

main
walon 2022-02-10 15:07:09 +08:00
parent 45f4a13dd2
commit 6b1669e050
15 changed files with 207 additions and 66 deletions

View File

@ -132,7 +132,7 @@ namespace Luban.Job.Cfg.DataConverts
{
if (!x.SubTitles.TryGetValue(DefBean.TYPE_NAME_KEY, out var typeTitle))
{
throw new Exception($"多态bean:{data.Type.FullName} 缺失 __type__ 标题列");
throw new Exception($"多态bean:{data.Type.FullName} 缺失 {DefBean.TYPE_NAME_KEY} 标题列");
}
if (data.ImplType != null)
{

View File

@ -789,7 +789,6 @@ namespace Luban.Job.Cfg.Defs
Sep = XmlUtil.GetOptionalAttribute(e, "sep"),
Comment = XmlUtil.GetOptionalAttribute(e, "comment"),
Tags = XmlUtil.GetOptionalAttribute(e, "tags"),
ExternalType = XmlUtil.GetOptionalAttribute(e, "externaltype"),
};
var childBeans = new List<XElement>();

View File

@ -359,6 +359,11 @@ namespace Luban.Job.Cfg.Defs
throw;
}
}
foreach (var externalType in defines.ExternalTypes.Values)
{
AddExternalType(externalType);
}
}
}
}

View File

@ -12,6 +12,7 @@ namespace Luban.Job.Cfg.Defs
{
public const string TYPE_NAME_KEY = "__type__";
public const string BEAN_NULL_STR = "null";
public const string BEAN_NOT_NULL_STR = "{}";
@ -168,8 +169,6 @@ namespace Luban.Job.Cfg.Defs
public override void Compile()
{
ResolveExternalType();
var cs = new List<DefBeanBase>();
if (Children != null)
{

View File

@ -28,7 +28,7 @@ namespace Luban.Job.Cfg.Defs
// 如果ref了多个表不再生成 xxx_ref之类的字段也不会resolve
public bool GenRef => Ref != null && Ref.GenRef;
public bool HasRecursiveRef => (CType is TBean tb && tb.Bean.CurrentExternalTypeMapper == null)
public bool HasRecursiveRef => (CType is TBean tb && HostType.AssemblyBase.GetExternalTypeMapper(tb) == null)
|| (CType is TArray ta && ta.ElementType.IsBean)
|| (CType is TList tl && tl.ElementType.IsBean)
|| (CType is TMap tm && tm.ValueType.IsBean);

View File

@ -217,7 +217,7 @@ namespace Luban.Job.Common.Defs
private static readonly List<string> _beanOptinsAttrs1 = new List<string> { "compatible", "value_type", "comment", "tags", "externaltype" };
private static readonly List<string> _beanRequireAttrs1 = new List<string> { "id", "name" };
private static readonly List<string> _beanOptinsAttrs2 = new List<string> { "id", "parent", "compatible", "value_type", "comment", "tags", "externaltype" };
private static readonly List<string> _beanOptinsAttrs2 = new List<string> { "id", "parent", "compatible", "value_type", "comment", "tags"};
private static readonly List<string> _beanRequireAttrs2 = new List<string> { "name" };
@ -257,7 +257,6 @@ namespace Luban.Job.Common.Defs
IsValueType = XmlUtil.GetOptionBoolAttribute(e, "value_type"),
Comment = XmlUtil.GetOptionalAttribute(e, "comment"),
Tags = XmlUtil.GetOptionalAttribute(e, "tags"),
ExternalType = XmlUtil.GetOptionalAttribute(e, "externaltype"),
};
var childBeans = new List<XElement>();
@ -321,7 +320,7 @@ namespace Luban.Job.Common.Defs
}
}
private static readonly List<string> _enumOptionalAttrs = new List<string> { "flags", "comment", "tags", "unique", "externaltype" };
private static readonly List<string> _enumOptionalAttrs = new List<string> { "flags", "comment", "tags", "unique" };
private static readonly List<string> _enumRequiredAttrs = new List<string> { "name" };
@ -339,7 +338,6 @@ namespace Luban.Job.Common.Defs
IsFlags = XmlUtil.GetOptionBoolAttribute(e, "flags"),
Tags = XmlUtil.GetOptionalAttribute(e, "tags"),
IsUniqueItemId = XmlUtil.GetOptionBoolAttribute(e, "unique", true),
ExternalType = XmlUtil.GetOptionalAttribute(e, "externaltype"),
};
foreach (XElement item in e.Elements())
@ -370,7 +368,7 @@ namespace Luban.Job.Common.Defs
s_logger.Trace("add selector:{}", name);
}
private static readonly List<string> _externalRequiredAttrs = new List<string> { "name" };
private static readonly List<string> _externalRequiredAttrs = new List<string> { "name", "origin_type_name" };
private void AddExternalType(string defineFile, XElement e)
{
ValidAttrKeys(_rootXml, e, null, _externalRequiredAttrs);
@ -384,6 +382,7 @@ namespace Luban.Job.Common.Defs
var et = new ExternalType()
{
Name = name,
OriginTypeName = XmlUtil.GetRequiredAttribute(e, "origin_type_name"),
};
var mappers = new Dictionary<string, ExternalTypeMapper>();
foreach (XElement mapperEle in e.Elements())
@ -424,9 +423,9 @@ namespace Luban.Job.Common.Defs
var tagName = attrEle.Name.LocalName;
switch (tagName)
{
case "typename":
case "target_type_name":
{
m.TypeName = attrEle.Value;
m.TargetTypeName = attrEle.Value;
break;
}
case "create_external_object_function":
@ -437,9 +436,9 @@ namespace Luban.Job.Common.Defs
default: throw new LoadDefException($"定义文件:{defineFile} externaltype:{externalType} 非法 tag:{tagName}");
}
}
if (string.IsNullOrWhiteSpace(m.TypeName))
if (string.IsNullOrWhiteSpace(m.TargetTypeName))
{
throw new LoadDefException($"定义文件:{defineFile} externaltype:{externalType} lan:{m.Lan} selector:{m.Selector} 没有定义 typename");
throw new LoadDefException($"定义文件:{defineFile} externaltype:{externalType} lan:{m.Lan} selector:{m.Selector} 没有定义 'target_type_name'");
}
return m;
}

View File

@ -2,6 +2,7 @@
using Luban.Common.Utils;
using Luban.Job.Common.RawDefs;
using Luban.Job.Common.Types;
using Luban.Job.Common.TypeVisitors;
using Luban.Job.Common.Utils;
using Luban.Server.Common;
using System;
@ -61,6 +62,8 @@ namespace Luban.Job.Common.Defs
private Dictionary<string, ExternalType> ExternalTypes { get; set; }
private readonly Dictionary<string, ExternalType> _externalTypesByTypeName = new();
public List<string> CurrentExternalSelectors { get; private set; }
public Dictionary<string, string> Options { get; private set; }
@ -119,9 +122,45 @@ namespace Luban.Job.Common.Defs
NamingConventionEnumMember = args.NamingConventionEnumMember;
}
public bool TryGetExternalType(string typeName, out ExternalType type)
public ExternalTypeMapper GetExternalTypeMapper(TType type)
{
return ExternalTypes.TryGetValue(typeName, out type);
return GetExternalTypeMapper(type.Apply(RawDefineTypeNameVisitor.Ins));
}
public ExternalTypeMapper GetExternalTypeMapper(string typeName)
{
ExternalType externalType = _externalTypesByTypeName.GetValueOrDefault(typeName);
if (externalType == null)
{
return null;
}
return externalType.Mappers.Find(m => m.Lan == CurrentLanguage && CurrentExternalSelectors.Contains(m.Selector));
}
public ExternalType GetExternalType(string typeName)
{
return _externalTypesByTypeName.GetValueOrDefault(typeName);
}
private static readonly HashSet<string> s_internalOriginTypes = new HashSet<string>
{
"vector2",
"vector3",
"vector4",
"datetime",
};
public void AddExternalType(ExternalType type)
{
string originTypeName = type.OriginTypeName;
if (!Types.ContainsKey(originTypeName) && !s_internalOriginTypes.Contains(originTypeName))
{
throw new LoadDefException($"externaltype:'{type.Name}' originTypeName:'{originTypeName}' 不存在");
}
if (!_externalTypesByTypeName.TryAdd(originTypeName, type))
{
throw new LoadDefException($"type:'{originTypeName} 被重复映射. externaltype1:'{type.Name}' exteraltype2:'{_externalTypesByTypeName[originTypeName].Name}'");
}
}
public void AddType(DefTypeBase type)

View File

@ -52,7 +52,6 @@ namespace Luban.Job.Common.Defs
IsValueType = b.IsValueType;
Comment = b.Comment;
Tags = DefUtil.ParseAttrs(b.Tags);
_externalTypeName = b.ExternalType;
foreach (var field in b.Fields)
{
Fields.Add(CreateField(field, 0));
@ -159,8 +158,6 @@ namespace Luban.Job.Common.Defs
public override void Compile()
{
base.Compile();
var cs = new List<DefBeanBase>();
if (Children != null)
{

View File

@ -99,7 +99,6 @@ namespace Luban.Job.Common.Defs
IsUniqueItemId = e.IsUniqueItemId;
Comment = e.Comment;
Tags = DefUtil.ParseAttrs(e.Tags);
_externalTypeName = e.ExternalType;
foreach (var item in e.Items)
{
Items.Add(new Item
@ -116,7 +115,6 @@ namespace Luban.Job.Common.Defs
public override void Compile()
{
base.Compile();
var fullName = FullName;
int lastEnumValue = -1;

View File

@ -21,10 +21,6 @@ namespace Luban.Job.Common.Defs
public string Namespace { get; set; }
protected string _externalTypeName;
public ExternalType ExternalType { get; private set; }
public string FullName => TypeUtil.MakeFullName(Namespace, Name);
public string NamespaceWithTopModule => TypeUtil.MakeNamespace(AssemblyBase.TopModule, Namespace);
@ -79,40 +75,9 @@ namespace Luban.Job.Common.Defs
return Tags != null && Tags.TryGetValue(attrName, out var value) ? value : null;
}
public ExternalTypeMapper CurrentExternalTypeMapper
{
get
{
if (ExternalType == null)
{
return null;
}
return ExternalType.Mappers.Find(m => m.Lan == this.AssemblyBase.CurrentLanguage && this.AssemblyBase.CurrentExternalSelectors.Contains(m.Selector));
}
}
protected void ResolveExternalType()
{
if (!string.IsNullOrEmpty(_externalTypeName))
{
if (AssemblyBase.TryGetExternalType(_externalTypeName, out var type))
{
this.ExternalType = type;
}
else
{
throw new Exception($"enum:'{FullName}' ¶ÔÓ¦µÄ externaltype:{_externalTypeName} ²»´æÔÚ");
}
}
}
public virtual void PreCompile() { }
public virtual void Compile()
{
ResolveExternalType();
}
public abstract void Compile();
public virtual void PostCompile() { }
}

View File

@ -22,8 +22,6 @@ namespace Luban.Job.Common.RawDefs
public string Tags { get; set; }
public string ExternalType { get; set; }
public List<Field> Fields { get; set; } = new List<Field>();
}
}

View File

@ -13,7 +13,7 @@ namespace Luban.Job.Common.RawDefs
public ELanguage Lan { get; set; }
public string TypeName { get; set; }
public string TargetTypeName { get; set; }
public string CreateExternalObjectFunction { get; set; }
}
@ -22,6 +22,8 @@ namespace Luban.Job.Common.RawDefs
{
public string Name { get; set; }
public string OriginTypeName { get; set; }
public List<ExternalTypeMapper> Mappers { get; set; } = new List<ExternalTypeMapper>();
}
}

View File

@ -30,8 +30,6 @@ namespace Luban.Job.Common.RawDefs
public string Tags { get; set; }
public string ExternalType { get; set; }
public List<EnumItem> Items { get; set; } = new List<EnumItem>();
}
}

View File

@ -0,0 +1,124 @@
using Luban.Job.Common.Types;
namespace Luban.Job.Common.TypeVisitors
{
public class RawDefineTypeNameVisitor : ITypeFuncVisitor<string>
{
public static RawDefineTypeNameVisitor Ins { get; } = new ();
public string Accept(TBool type)
{
return "bool";
}
public string Accept(TByte type)
{
return "byte";
}
public string Accept(TShort type)
{
return "short";
}
public string Accept(TFshort type)
{
return "fshort";
}
public string Accept(TInt type)
{
return "int";
}
public string Accept(TFint type)
{
return "fint";
}
public string Accept(TLong type)
{
return "long";
}
public string Accept(TFlong type)
{
return "flong";
}
public string Accept(TFloat type)
{
return "float";
}
public string Accept(TDouble type)
{
return "double";
}
public string Accept(TEnum type)
{
return type.DefineEnum.FullName;
}
public string Accept(TString type)
{
return "string";
}
public string Accept(TBytes type)
{
return "bytes";
}
public string Accept(TText type)
{
return "string";
}
public string Accept(TBean type)
{
return type.Bean.FullName;
}
public string Accept(TArray type)
{
return $"array,{type.ElementType.Apply(this)}";
}
public string Accept(TList type)
{
return $"list,{type.ElementType.Apply(this)}";
}
public string Accept(TSet type)
{
return $"set,{type.ElementType.Apply(this)}";
}
public string Accept(TMap type)
{
return $"map,{type.KeyType.Apply(this)},{type.ValueType.Apply(this)}";
}
public string Accept(TVector2 type)
{
return "vector2";
}
public string Accept(TVector3 type)
{
return "vector3";
}
public string Accept(TVector4 type)
{
return "vector4";
}
public virtual string Accept(TDateTime type)
{
return "datetime";
}
}
}

View File

@ -1,4 +1,6 @@
using Luban.Job.Common.Defs;
using Luban.Job.Common.RawDefs;
using Luban.Job.Common.Types;
using System;
using System.Collections.Generic;
using System.Linq;
@ -9,22 +11,38 @@ namespace Luban.Job.Common.Utils
{
public static class ExternalTypeUtil
{
//protected void ResolveExternalType()
//{
// if (!string.IsNullOrEmpty(_externalTypeName))
// {
// if (AssemblyBase.TryGetExternalType(_externalTypeName, out var type))
// {
// this.ExternalType = type;
// }
// else
// {
// throw new Exception($"enum:'{FullName}' 对应的 externaltype:{_externalTypeName} 不存在");
// }
// }
//}
public static string CsMapperToExternalType(DefTypeBase type)
{
var mapper = type.CurrentExternalTypeMapper;
return mapper != null ? mapper.TypeName : type.CsFullName;
var mapper = DefAssemblyBase.LocalAssebmly.GetExternalTypeMapper(type.FullName);
return mapper != null ? mapper.TargetTypeName : type.CsFullName;
}
public static string CsCloneToExternal(DefTypeBase type, string src)
{
var mapper = type.CurrentExternalTypeMapper;
var mapper = DefAssemblyBase.LocalAssebmly.GetExternalTypeMapper(type.FullName);
if (mapper == null)
{
return src;
}
if (string.IsNullOrWhiteSpace(mapper.CreateExternalObjectFunction))
{
throw new Exception($"type:{type.FullName} externaltype:{type.ExternalType.Name} lan:{mapper.Lan} selector:{mapper.Selector} 未定义clone_to_external元素");
throw new Exception($"type:{type.FullName} externaltype:{DefAssemblyBase.LocalAssebmly.GetExternalType(type.FullName)} lan:{mapper.Lan} selector:{mapper.Selector} 未定义 create_external_object_function 属性");
}
return $"{mapper.CreateExternalObjectFunction}({src})";
}