【特性】支持子bean在其他地方,包括其他模块从父类继承

main
walon 2022-01-29 14:28:03 +08:00
parent 9f687adcf1
commit b3457da8d2
26 changed files with 87 additions and 59 deletions

View File

@ -396,12 +396,7 @@ namespace Luban.Job.Cfg.DataCreators
}
return null;
}
string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
if (implType == null)
{
throw new InvalidExcelDataException($"type:{fullType} 不是bean类型");
}
DefBean implType = DataUtil.GetImplTypeByNameOrAlias(originBean, subType);
return new DBean(type, implType, CreateBeanFields(implType, x));
}
else

View File

@ -117,13 +117,7 @@ namespace Luban.Job.Cfg.DataCreators
throw new Exception($"结构:'{bean.FullName}' 是多态类型,必须用 '{DefBean.TYPE_NAME_KEY}' 字段指定 子类名");
}
string subType = typeNameProp.GetString();
var fullName = TypeUtil.MakeFullName(bean.Namespace, subType);
var defType = (DefBean)bean.GetNotAbstractChildType(subType);
//if (defType.IsAbstractType)
//{
// throw new Exception($"type:{fullName} 是抽象类. 不能创建实例");
//}
implBean = defType ?? throw new Exception($"type:'{fullName}' 不是合法类型");
implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType);
}
else
{

View File

@ -158,14 +158,7 @@ namespace Luban.Job.Cfg.DataCreators
throw new Exception($"结构:{bean.FullName} 是多态类型,必须用 {DefBean.TYPE_NAME_KEY} 字段指定 子类名");
}
var subType = (string)table[DefBean.TYPE_NAME_KEY];
string fullName = TypeUtil.MakeFullName(bean.Namespace, subType);
var defType = (DefBean)bean.GetNotAbstractChildType(subType);
//if (defType.IsAbstractType)
//{
// throw new Exception($"type:{fullName} 是抽象类. 不能创建实例");
//}
implBean = defType ?? throw new Exception($"type:{fullName} 不是合法类型");
implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType);
}
else
{

View File

@ -414,12 +414,7 @@ namespace Luban.Job.Cfg.DataCreators
}
return null;
}
string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
if (implType == null)
{
throw new Exception($"type:'{fullType}' 不是 bean 类型或者不是'{originBean.FullName}'的子类");
}
DefBean implType = DataUtil.GetImplTypeByNameOrAlias(originBean, subType);
return new DBean(type, implType, CreateBeanFields(implType, sheet, row));
}
else

View File

@ -101,13 +101,7 @@ namespace Luban.Job.Cfg.DataCreators
{
throw new Exception($"bean:'{bean.FullName}'是多态,需要指定{DefBean.TYPE_NAME_KEY}属性.\n xml:{x}");
}
var fullName = TypeUtil.MakeFullName(bean.Namespace, subType);
var defType = (DefBean)bean.GetNotAbstractChildType(subType);
//if (defType.IsAbstractType)
//{
// throw new Exception($"type:{fullName} 是抽象类. 不能创建实例");
//}
implBean = defType ?? throw new Exception($"type:'{fullName}' 不是合法类型");
implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType);
}
else
{

View File

@ -117,9 +117,7 @@ namespace Luban.Job.Cfg.DataCreators
{
throw new Exception($"bean:'{bean.FullName}'是多态,需要指定{DefBean.TYPE_NAME_KEY}属性.\n xml:{x}");
}
var fullName = TypeUtil.MakeFullName(bean.Namespace, subType);
var defType = (DefBean)bean.GetNotAbstractChildType(subType);
implBean = defType ?? throw new Exception($"type:'{fullName}' 不是合法类型");
implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType);
}
else
{

View File

@ -2,6 +2,7 @@ using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.Utils;
using System;
using System.Collections.Generic;
using System.Text.Json;
@ -104,7 +105,7 @@ namespace Luban.Job.Cfg.DataExporters
if (type.Type.IsAbstractType)
{
x.WritePropertyName(DefBean.TYPE_NAME_KEY);
x.WriteStringValue(type.ImplType.Name);
x.WriteStringValue(DataUtil.GetImplTypeName(type));
}
var defFields = type.ImplType.HierarchyFields;

View File

@ -2,6 +2,7 @@
using Luban.Job.Cfg.DataSources;
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.Utils;
using MessagePack;
using System;
using System.Collections.Generic;
@ -183,7 +184,7 @@ namespace Luban.Job.Cfg.DataExporters
if (type.Type.IsAbstractType)
{
writer.Write(DefBean.TYPE_NAME_KEY);
writer.Write(type.ImplType.Name);
writer.Write(DataUtil.GetImplTypeName(type));
}
int index = 0;

View File

@ -105,7 +105,7 @@ namespace Luban.Job.Cfg.DataExporters
if (type.Type.IsAbstractType)
{
x.WritePropertyName(DefBean.TYPE_NAME_KEY);
x.WriteStringValue(type.ImplType.Name);
x.WriteStringValue(DataUtil.GetImplTypeName(type));
}
var defFields = type.ImplType.HierarchyFields;

View File

@ -20,7 +20,7 @@ namespace Luban.Job.Cfg.DataVisitors
var x = new StringBuilder();
if (type.Type.IsAbstractType)
{
x.Append($"#{{name__ => \"{type.ImplType.Name}\"");
x.Append($"#{{name__ => \"{DataUtil.GetImplTypeName(type)}\"");
if (type.Fields.Count > 0)
{
x.Append(',');

View File

@ -20,7 +20,7 @@ namespace Luban.Job.Cfg.DataVisitors
var x = new StringBuilder();
if (type.Type.IsAbstractType)
{
x.Append($"{{ _name='{type.ImplType.Name}',");
x.Append($"{{ _name='{DataUtil.GetImplTypeName(type)}',");
}
else
{

View File

@ -775,18 +775,18 @@ namespace Luban.Job.Cfg.Defs
return f;
}
private static readonly List<string> _beanOptinsAttrs = new List<string> { "value_type", "alias", "sep", "comment", "tags", "externaltype" };
private static readonly List<string> _beanOptinsAttrs = new List<string> { "parent", "value_type", "alias", "sep", "comment", "tags", "externaltype" };
private static readonly List<string> _beanRequireAttrs = new List<string> { "name" };
override protected void AddBean(string defineFile, XElement e, string parent)
{
ValidAttrKeys(defineFile, e, _beanOptinsAttrs, _beanRequireAttrs);
TryGetUpdateParent(e, ref parent);
var b = new CfgBean()
{
Name = XmlUtil.GetRequiredAttribute(e, "name"),
Namespace = CurNamespace,
Parent = parent.Length > 0 ? parent : "",
Parent = parent,
TypeId = 0,
IsSerializeCompatible = true,
IsValueType = XmlUtil.GetOptionBoolAttribute(e, "value_type"),

View File

@ -173,7 +173,7 @@ namespace editor
if (_json->TryGetStringField(FString(""__type__""), type))
{
{{~for child in type.hierarchy_not_abstract_children~}}
if (type == ""{{child.name}}"")
if (type == ""{{cs_impl_data_type child x}}"")
{
result = new {{child.ue_fname}}();
} else

View File

@ -184,6 +184,41 @@ namespace Luban.Job.Cfg.Utils
return false;
}
public static string GetImplTypeName(DBean bean)
{
return GetImplTypeName(bean.ImplType, bean.Type);
}
public static string GetImplTypeName(DefBean implType, DefBean baseType)
{
if (implType.Namespace == baseType.Namespace)
{
return implType.Name;
}
else
{
return implType.FullName;
}
}
public static DefBean GetImplTypeByNameOrAlias(DefBean bean, string subType)
{
if (string.IsNullOrEmpty(subType))
{
throw new Exception($"module:'{bean.Namespace}' 多态数据type不能为空");
}
DefBean defType = bean.HierarchyNotAbstractChildren.Cast<DefBean>().Where(c => c.Alias == subType || c.Name == subType || c.FullName == subType).FirstOrDefault();
if (defType == null)
{
throw new Exception($"module:'{bean.Namespace}' type:'{subType}' 不是合法类型");
}
if (defType.IsAbstractType)
{
throw new Exception($"module:'{bean.Namespace}' type:'{subType}' 是抽象类. 不能创建实例");
}
return defType;
}
//public static string Data2String(DType data)
//{
// var s = new StringBuilder();

View File

@ -37,6 +37,11 @@ namespace Luban.Job.Cfg.Utils
}
}
public static string CsImplDataType(DefBean type, DefBean parent)
{
return DataUtil.GetImplTypeName(type, parent);
}
public static string CsUnityJsonDeserialize(string bufName, string fieldName, string jsonFieldName, TType type)
{
if (type.IsNullable)

View File

@ -217,11 +217,26 @@ 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", "compatible", "value_type", "comment", "tags", "externaltype" };
private static readonly List<string> _beanOptinsAttrs2 = new List<string> { "id", "parent", "compatible", "value_type", "comment", "tags", "externaltype" };
private static readonly List<string> _beanRequireAttrs2 = new List<string> { "name" };
protected void TryGetUpdateParent(XElement e, ref string parent)
{
string selfDefParent = XmlUtil.GetOptionalAttribute(e, "parent");
if (!string.IsNullOrEmpty(selfDefParent))
{
if (!string.IsNullOrEmpty(parent))
{
throw new Exception($"嵌套在'{parent}'中定义的子bean:'{XmlUtil.GetRequiredAttribute(e, "name")}' 不能再定义parent:{selfDefParent} 属性");
}
parent = selfDefParent;
}
}
protected virtual void AddBean(string defineFile, XElement e, string parent)
{
if (IsBeanFieldMustDefineId)
{
ValidAttrKeys(defineFile, e, _beanOptinsAttrs1, _beanRequireAttrs1);
@ -230,11 +245,13 @@ namespace Luban.Job.Common.Defs
{
ValidAttrKeys(defineFile, e, _beanOptinsAttrs2, _beanRequireAttrs2);
}
TryGetUpdateParent(e, ref parent);
var b = new Bean()
{
Name = XmlUtil.GetRequiredAttribute(e, "name").Trim(),
Namespace = CurNamespace,
Parent = parent.Length > 0 ? parent : "",
Parent = parent,
TypeId = XmlUtil.GetOptionIntAttribute(e, "id"),
IsSerializeCompatible = XmlUtil.GetOptionBoolAttribute(e, "compatible", IsBeanDefaultCompatible),
IsValueType = XmlUtil.GetOptionBoolAttribute(e, "value_type"),

View File

@ -141,11 +141,11 @@ namespace Luban.Job.Common.Defs
public DefTypeBase GetDefType(string module, string type)
{
if (Types.TryGetValue(type, out var t))
if (Types.TryGetValue(TypeUtil.MakeFullName(module, type), out var t))
{
return t;
}
else if (Types.TryGetValue(TypeUtil.MakeFullName(module, type), out t))
else if (Types.TryGetValue(type, out t))
{
return t;
}

View File

@ -48,7 +48,7 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
switch (_json.GetProperty("__type__").GetString())
{
{{~for child in x.hierarchy_not_abstract_children~}}
case "{{child.name}}": return new {{child.full_name}}(_json);
case "{{cs_impl_data_type child x}}": return new {{child.full_name}}(_json);
{{~end~}}
default: throw new SerializationException();
}

View File

@ -75,7 +75,7 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
switch (type)
{
{{~for child in x.hierarchy_not_abstract_children~}}
case "{{child.name}}": obj = new {{child.full_name}}(); break;
case "{{cs_impl_data_type child x}}": obj = new {{child.full_name}}(); break;
{{~end~}}
default: throw new SerializationException();
}

View File

@ -49,7 +49,7 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
switch (type)
{
{{~for child in x.hierarchy_not_abstract_children~}}
case "{{child.name}}": return new {{child.full_name}}(_json);
case "{{cs_impl_data_type child x}}": return new {{child.full_name}}(_json);
{{~end~}}
default: throw new SerializationException();
}

View File

@ -38,7 +38,7 @@ func Deserialize{{go_full_name}}(_buf map[string]interface{}) (interface{}, erro
}
switch id {
{{~for child in hierarchy_not_abstract_children~}}
case "{{child.name}}": _v := &{{child.go_full_name}}{}; if err := _v.Deserialize(_buf); err != nil { return nil, errors.New("{{child.full_name}}") } else { return _v, nil }
case "{{cs_impl_data_type child x}}": _v := &{{child.go_full_name}}{}; if err := _v.Deserialize(_buf); err != nil { return nil, errors.New("{{child.full_name}}") } else { return _v, nil }
{{~end~}}
default: return nil, errors.New("unknown type id")
}

View File

@ -48,7 +48,7 @@ public {{x.java_class_modifier}} class {{name}}{{if parent_def_type}} extends {{
{{~if x.is_abstract_type~}}
switch (__json__.get("__type__").getAsString()) {
{{~for child in x.hierarchy_not_abstract_children~}}
case "{{child.name}}": return new {{child.full_name_with_top_module}}(__json__);
case "{{cs_impl_data_type child x}}": return new {{child.full_name_with_top_module}}(__json__);
{{~end~}}
default: throw new bright.serialization.SerializationException();
}

View File

@ -17,7 +17,7 @@ class {{name}} {{if parent_def_type}}({{parent_def_type.py_full_name}}){{end}}:
if not childrenTypes:
childrenTypes = {{name}}._childrenTypes = {
{{~ for child in x.hierarchy_not_abstract_children~}}
'{{child.name}}': {{child.py_full_name}},
'{{cs_impl_data_type child x}}': {{child.py_full_name}},
{{~end~}}
}
type = _json_['__type__']

View File

@ -17,7 +17,7 @@ class {{name}} {{if parent_def_type}}({{parent_def_type.py_full_name}}){{else if
if not childrenTypes:
childrenTypes = {{name}}._childrenTypes = {
{{~ for child in x.hierarchy_not_abstract_children~}}
'{{child.name}}': {{child.py_full_name}},
'{{cs_impl_data_type child x}}': {{child.py_full_name}},
{{~end~}}
}
type = _json_['__type__']

View File

@ -44,7 +44,7 @@ impl {{name}} {
let __b = match __js["__type__"].as_str() {
Some(type_name) => match type_name {
{{~for child in x.hierarchy_not_abstract_children~}}
"{{child.name}}" => {{name}}::{{child.name}}(Box::new({{child.rust_full_name + '::new(&__js)?'}})),
"{{cs_impl_data_type child x}}" => {{name}}::{{child.name}}(Box::new({{child.rust_full_name + '::new(&__js)?'}})),
{{~end~}}
_ => return Err(LoadError{})
},

View File

@ -17,7 +17,7 @@ export {{if x.is_abstract_type}}abstract {{end}}class {{name}}{{if parent_def_ty
static constructorFrom(_json_: any): {{name}}{
switch (_json_.__type__) {
{{~ for child in x.hierarchy_not_abstract_children~}}
case '{{child.name}}': return new {{child.full_name}}(_json_)
case '{{cs_impl_data_type child x}}': return new {{child.full_name}}(_json_)
{{~end~}}
default: throw new Error()
}