【特性】支持子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; return null;
} }
string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType); DefBean implType = DataUtil.GetImplTypeByNameOrAlias(originBean, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
if (implType == null)
{
throw new InvalidExcelDataException($"type:{fullType} 不是bean类型");
}
return new DBean(type, implType, CreateBeanFields(implType, x)); return new DBean(type, implType, CreateBeanFields(implType, x));
} }
else else

View File

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

View File

@ -158,14 +158,7 @@ namespace Luban.Job.Cfg.DataCreators
throw new Exception($"结构:{bean.FullName} 是多态类型,必须用 {DefBean.TYPE_NAME_KEY} 字段指定 子类名"); throw new Exception($"结构:{bean.FullName} 是多态类型,必须用 {DefBean.TYPE_NAME_KEY} 字段指定 子类名");
} }
var subType = (string)table[DefBean.TYPE_NAME_KEY]; var subType = (string)table[DefBean.TYPE_NAME_KEY];
implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType);
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} 不是合法类型");
} }
else else
{ {

View File

@ -414,12 +414,7 @@ namespace Luban.Job.Cfg.DataCreators
} }
return null; return null;
} }
string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType); DefBean implType = DataUtil.GetImplTypeByNameOrAlias(originBean, subType);
DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType);
if (implType == null)
{
throw new Exception($"type:'{fullType}' 不是 bean 类型或者不是'{originBean.FullName}'的子类");
}
return new DBean(type, implType, CreateBeanFields(implType, sheet, row)); return new DBean(type, implType, CreateBeanFields(implType, sheet, row));
} }
else 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}"); throw new Exception($"bean:'{bean.FullName}'是多态,需要指定{DefBean.TYPE_NAME_KEY}属性.\n xml:{x}");
} }
var fullName = TypeUtil.MakeFullName(bean.Namespace, subType); implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType);
var defType = (DefBean)bean.GetNotAbstractChildType(subType);
//if (defType.IsAbstractType)
//{
// throw new Exception($"type:{fullName} 是抽象类. 不能创建实例");
//}
implBean = defType ?? throw new Exception($"type:'{fullName}' 不是合法类型");
} }
else 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}"); throw new Exception($"bean:'{bean.FullName}'是多态,需要指定{DefBean.TYPE_NAME_KEY}属性.\n xml:{x}");
} }
var fullName = TypeUtil.MakeFullName(bean.Namespace, subType); implBean = DataUtil.GetImplTypeByNameOrAlias(bean, subType);
var defType = (DefBean)bean.GetNotAbstractChildType(subType);
implBean = defType ?? throw new Exception($"type:'{fullName}' 不是合法类型");
} }
else else
{ {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -184,6 +184,41 @@ namespace Luban.Job.Cfg.Utils
return false; 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) //public static string Data2String(DType data)
//{ //{
// var s = new StringBuilder(); // 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) public static string CsUnityJsonDeserialize(string bufName, string fieldName, string jsonFieldName, TType type)
{ {
if (type.IsNullable) 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> _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> _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" }; 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) protected virtual void AddBean(string defineFile, XElement e, string parent)
{ {
if (IsBeanFieldMustDefineId) if (IsBeanFieldMustDefineId)
{ {
ValidAttrKeys(defineFile, e, _beanOptinsAttrs1, _beanRequireAttrs1); ValidAttrKeys(defineFile, e, _beanOptinsAttrs1, _beanRequireAttrs1);
@ -230,11 +245,13 @@ namespace Luban.Job.Common.Defs
{ {
ValidAttrKeys(defineFile, e, _beanOptinsAttrs2, _beanRequireAttrs2); ValidAttrKeys(defineFile, e, _beanOptinsAttrs2, _beanRequireAttrs2);
} }
TryGetUpdateParent(e, ref parent);
var b = new Bean() var b = new Bean()
{ {
Name = XmlUtil.GetRequiredAttribute(e, "name").Trim(), Name = XmlUtil.GetRequiredAttribute(e, "name").Trim(),
Namespace = CurNamespace, Namespace = CurNamespace,
Parent = parent.Length > 0 ? parent : "", Parent = parent,
TypeId = XmlUtil.GetOptionIntAttribute(e, "id"), TypeId = XmlUtil.GetOptionIntAttribute(e, "id"),
IsSerializeCompatible = XmlUtil.GetOptionBoolAttribute(e, "compatible", IsBeanDefaultCompatible), IsSerializeCompatible = XmlUtil.GetOptionBoolAttribute(e, "compatible", IsBeanDefaultCompatible),
IsValueType = XmlUtil.GetOptionBoolAttribute(e, "value_type"), IsValueType = XmlUtil.GetOptionBoolAttribute(e, "value_type"),

View File

@ -141,11 +141,11 @@ namespace Luban.Job.Common.Defs
public DefTypeBase GetDefType(string module, string type) 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; return t;
} }
else if (Types.TryGetValue(TypeUtil.MakeFullName(module, type), out t)) else if (Types.TryGetValue(type, out t))
{ {
return 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()) switch (_json.GetProperty("__type__").GetString())
{ {
{{~for child in x.hierarchy_not_abstract_children~}} {{~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~}} {{~end~}}
default: throw new SerializationException(); default: throw new SerializationException();
} }

View File

@ -75,7 +75,7 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
switch (type) switch (type)
{ {
{{~for child in x.hierarchy_not_abstract_children~}} {{~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~}} {{~end~}}
default: throw new SerializationException(); default: throw new SerializationException();
} }

View File

@ -49,7 +49,7 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} {
switch (type) switch (type)
{ {
{{~for child in x.hierarchy_not_abstract_children~}} {{~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~}} {{~end~}}
default: throw new SerializationException(); default: throw new SerializationException();
} }

View File

@ -38,7 +38,7 @@ func Deserialize{{go_full_name}}(_buf map[string]interface{}) (interface{}, erro
} }
switch id { switch id {
{{~for child in hierarchy_not_abstract_children~}} {{~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~}} {{~end~}}
default: return nil, errors.New("unknown type id") 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~}} {{~if x.is_abstract_type~}}
switch (__json__.get("__type__").getAsString()) { switch (__json__.get("__type__").getAsString()) {
{{~for child in x.hierarchy_not_abstract_children~}} {{~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~}} {{~end~}}
default: throw new bright.serialization.SerializationException(); 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: if not childrenTypes:
childrenTypes = {{name}}._childrenTypes = { childrenTypes = {{name}}._childrenTypes = {
{{~ for child in x.hierarchy_not_abstract_children~}} {{~ 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~}} {{~end~}}
} }
type = _json_['__type__'] 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: if not childrenTypes:
childrenTypes = {{name}}._childrenTypes = { childrenTypes = {{name}}._childrenTypes = {
{{~ for child in x.hierarchy_not_abstract_children~}} {{~ 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~}} {{~end~}}
} }
type = _json_['__type__'] type = _json_['__type__']

View File

@ -44,7 +44,7 @@ impl {{name}} {
let __b = match __js["__type__"].as_str() { let __b = match __js["__type__"].as_str() {
Some(type_name) => match type_name { Some(type_name) => match type_name {
{{~for child in x.hierarchy_not_abstract_children~}} {{~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~}} {{~end~}}
_ => return Err(LoadError{}) _ => 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}}{ static constructorFrom(_json_: any): {{name}}{
switch (_json_.__type__) { switch (_json_.__type__) {
{{~ for child in x.hierarchy_not_abstract_children~}} {{~ 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~}} {{~end~}}
default: throw new Error() default: throw new Error()
} }