【text】根据本地化 TextTable 对Text作转换

main
walon 2021-06-17 12:51:35 +08:00
parent 35bafee063
commit 97c2342cfc
27 changed files with 503 additions and 207 deletions

View File

@ -23,11 +23,11 @@ namespace Luban.Job.Cfg.Cache
{ {
public DefTable Table { get; } public DefTable Table { get; }
public List<DType> Records { get; } public List<Record> Records { get; }
public volatile int LastAccessTime; public volatile int LastAccessTime;
public FileRecordCache(DefTable table, List<DType> records) public FileRecordCache(DefTable table, List<Record> records)
{ {
Table = table; Table = table;
Records = records; Records = records;
@ -39,7 +39,7 @@ namespace Luban.Job.Cfg.Cache
private readonly object _shrinkLocker = new object(); private readonly object _shrinkLocker = new object();
public bool TryGetCacheLoadedRecords(DefTable table, string md5, string originFile, string sheetName, bool exportTestData, out List<DType> cacheRecords) public bool TryGetCacheLoadedRecords(DefTable table, string md5, string originFile, string sheetName, bool exportTestData, out List<Record> cacheRecords)
{ {
// TODO text localization check // TODO text localization check
cacheRecords = null; cacheRecords = null;
@ -60,7 +60,7 @@ namespace Luban.Job.Cfg.Cache
} }
} }
public void AddCacheLoadedRecords(DefTable table, string md5, string sheetName, bool exportTestData, List<DType> cacheRecords) public void AddCacheLoadedRecords(DefTable table, string md5, string sheetName, bool exportTestData, List<Record> cacheRecords)
{ {
lock (_shrinkLocker) lock (_shrinkLocker)
{ {

View File

@ -132,12 +132,12 @@ namespace Luban.Job.Cfg.DataSources.Excel
return Titles.TryGetValue(name, out var title) ? title : null; return Titles.TryGetValue(name, out var title) ? title : null;
} }
public ExcelStream GetColumn(string name, string sep) public ExcelStream GetColumn(string name, string sep, bool namedMode)
{ {
if (Titles.TryGetValue(name, out var title)) if (Titles.TryGetValue(name, out var title))
{ {
CheckEmptySinceSecondRow(name, title.FromIndex, title.ToIndex); CheckEmptySinceSecondRow(name, title.FromIndex, title.ToIndex);
var es = new ExcelStream(Rows[0], title.FromIndex, title.ToIndex, sep, true); var es = new ExcelStream(Rows[0], title.FromIndex, title.ToIndex, sep, namedMode);
return es; return es;
} }
else else

View File

@ -6,81 +6,90 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.DataVisitors namespace Luban.Job.Cfg.DataVisitors
{ {
class BinaryExportor : IDataActionVisitor<ByteBuf> class BinaryExportor : IDataActionVisitor<DefAssembly, ByteBuf>
{ {
public static BinaryExportor Ins { get; } = new BinaryExportor(); public static BinaryExportor Ins { get; } = new BinaryExportor();
public void Accept(DBool type, ByteBuf x) public void WriteList(List<Record> datas, DefAssembly ass, ByteBuf x)
{
x.WriteSize(datas.Count);
foreach (var d in datas)
{
d.Data.Apply(this, ass, x);
}
}
public void Accept(DBool type, DefAssembly ass, ByteBuf x)
{ {
x.WriteBool(type.Value); x.WriteBool(type.Value);
} }
public void Accept(DByte type, ByteBuf x) public void Accept(DByte type, DefAssembly ass, ByteBuf x)
{ {
x.WriteByte(type.Value); x.WriteByte(type.Value);
} }
public void Accept(DShort type, ByteBuf x) public void Accept(DShort type, DefAssembly ass, ByteBuf x)
{ {
x.WriteShort(type.Value); x.WriteShort(type.Value);
} }
public void Accept(DFshort type, ByteBuf x) public void Accept(DFshort type, DefAssembly ass, ByteBuf x)
{ {
x.WriteFshort(type.Value); x.WriteFshort(type.Value);
} }
public void Accept(DInt type, ByteBuf x) public void Accept(DInt type, DefAssembly ass, ByteBuf x)
{ {
x.WriteInt(type.Value); x.WriteInt(type.Value);
} }
public void Accept(DFint type, ByteBuf x) public void Accept(DFint type, DefAssembly ass, ByteBuf x)
{ {
x.WriteFint(type.Value); x.WriteFint(type.Value);
} }
public void Accept(DLong type, ByteBuf x) public void Accept(DLong type, DefAssembly ass, ByteBuf x)
{ {
x.WriteLong(type.Value); x.WriteLong(type.Value);
} }
public void Accept(DFlong type, ByteBuf x) public void Accept(DFlong type, DefAssembly ass, ByteBuf x)
{ {
x.WriteFlong(type.Value); x.WriteFlong(type.Value);
} }
public void Accept(DFloat type, ByteBuf x) public void Accept(DFloat type, DefAssembly ass, ByteBuf x)
{ {
x.WriteFloat(type.Value); x.WriteFloat(type.Value);
} }
public void Accept(DDouble type, ByteBuf x) public void Accept(DDouble type, DefAssembly ass, ByteBuf x)
{ {
x.WriteDouble(type.Value); x.WriteDouble(type.Value);
} }
public void Accept(DEnum type, ByteBuf x) public void Accept(DEnum type, DefAssembly ass, ByteBuf x)
{ {
x.WriteInt(type.Value); x.WriteInt(type.Value);
} }
public void Accept(DString type, ByteBuf x) public void Accept(DString type, DefAssembly ass, ByteBuf x)
{ {
x.WriteString(type.Value); x.WriteString(type.Value);
} }
public void Accept(DBytes type, ByteBuf x) public void Accept(DBytes type, DefAssembly ass, ByteBuf x)
{ {
x.WriteBytes(type.Value); x.WriteBytes(type.Value);
} }
public void Accept(DText type, ByteBuf x) public void Accept(DText type, DefAssembly ass, ByteBuf x)
{ {
x.WriteString(type.Value); x.WriteString(type.GetText(ass.ExportTextTable, ass.NotConvertTextSet));
} }
public void Accept(DBean type, ByteBuf x) public void Accept(DBean type, DefAssembly ass, ByteBuf x)
{ {
var bean = type.Type; var bean = type.Type;
if (bean.IsAbstractType) if (bean.IsAbstractType)
@ -108,7 +117,7 @@ namespace Luban.Job.Cfg.DataVisitors
if (field != null) if (field != null)
{ {
x.WriteBool(true); x.WriteBool(true);
field.Apply(this, x); field.Apply(this, ass, x);
} }
else else
{ {
@ -117,62 +126,62 @@ namespace Luban.Job.Cfg.DataVisitors
} }
else else
{ {
field.Apply(this, x); field.Apply(this, ass, x);
} }
} }
} }
public void WriteList(List<DType> datas, ByteBuf x) public void WriteList(List<DType> datas, DefAssembly ass, ByteBuf x)
{ {
x.WriteSize(datas.Count); x.WriteSize(datas.Count);
foreach (var d in datas) foreach (var d in datas)
{ {
d.Apply(this, x); d.Apply(this, ass, x);
} }
} }
public void Accept(DArray type, ByteBuf x) public void Accept(DArray type, DefAssembly ass, ByteBuf x)
{ {
WriteList(type.Datas, x); WriteList(type.Datas, ass, x);
} }
public void Accept(DList type, ByteBuf x) public void Accept(DList type, DefAssembly ass, ByteBuf x)
{ {
WriteList(type.Datas, x); WriteList(type.Datas, ass, x);
} }
public void Accept(DSet type, ByteBuf x) public void Accept(DSet type, DefAssembly ass, ByteBuf x)
{ {
WriteList(type.Datas, x); WriteList(type.Datas, ass, x);
} }
public void Accept(DMap type, ByteBuf x) public void Accept(DMap type, DefAssembly ass, ByteBuf x)
{ {
Dictionary<DType, DType> datas = type.Datas; Dictionary<DType, DType> datas = type.Datas;
x.WriteSize(datas.Count); x.WriteSize(datas.Count);
foreach (var e in datas) foreach (var e in datas)
{ {
e.Key.Apply(this, x); e.Key.Apply(this, ass, x);
e.Value.Apply(this, x); e.Value.Apply(this, ass, x);
} }
} }
public void Accept(DVector2 type, ByteBuf x) public void Accept(DVector2 type, DefAssembly ass, ByteBuf x)
{ {
x.WriteVector2(type.Value); x.WriteVector2(type.Value);
} }
public void Accept(DVector3 type, ByteBuf x) public void Accept(DVector3 type, DefAssembly ass, ByteBuf x)
{ {
x.WriteVector3(type.Value); x.WriteVector3(type.Value);
} }
public void Accept(DVector4 type, ByteBuf x) public void Accept(DVector4 type, DefAssembly ass, ByteBuf x)
{ {
x.WriteVector4(type.Value); x.WriteVector4(type.Value);
} }
public void Accept(DDateTime type, ByteBuf x) public void Accept(DDateTime type, DefAssembly ass, ByteBuf x)
{ {
x.WriteInt(type.UnixTime); x.WriteInt(type.UnixTime);
} }

View File

@ -75,7 +75,7 @@ namespace Luban.Job.Cfg.DataVisitors
public bool Accept(DText type) public bool Accept(DText type)
{ {
return string.IsNullOrEmpty(type.Value); return string.IsNullOrEmpty(type.Key);
} }
public bool Accept(DBean type) public bool Accept(DBean type)

View File

@ -6,81 +6,91 @@ using System.Text.Json;
namespace Luban.Job.Cfg.DataVisitors namespace Luban.Job.Cfg.DataVisitors
{ {
class JsonExportor : IDataActionVisitor<Utf8JsonWriter> class JsonExportor : IDataActionVisitor<DefAssembly, Utf8JsonWriter>
{ {
public static JsonExportor Ins { get; } = new JsonExportor(); public static JsonExportor Ins { get; } = new JsonExportor();
public void Accept(DBool type, Utf8JsonWriter x) public void WriteList(List<Record> datas, DefAssembly ass, Utf8JsonWriter x)
{
x.WriteStartArray();
foreach (var d in datas)
{
d.Data.Apply(this, ass, x);
}
x.WriteEndArray();
}
public void Accept(DBool type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteBooleanValue(type.Value); x.WriteBooleanValue(type.Value);
} }
public void Accept(DByte type, Utf8JsonWriter x) public void Accept(DByte type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DShort type, Utf8JsonWriter x) public void Accept(DShort type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DFshort type, Utf8JsonWriter x) public void Accept(DFshort type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DInt type, Utf8JsonWriter x) public void Accept(DInt type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DFint type, Utf8JsonWriter x) public void Accept(DFint type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DLong type, Utf8JsonWriter x) public void Accept(DLong type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DFlong type, Utf8JsonWriter x) public void Accept(DFlong type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DFloat type, Utf8JsonWriter x) public void Accept(DFloat type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DDouble type, Utf8JsonWriter x) public void Accept(DDouble type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DEnum type, Utf8JsonWriter x) public void Accept(DEnum type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.Value); x.WriteNumberValue(type.Value);
} }
public void Accept(DString type, Utf8JsonWriter x) public void Accept(DString type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStringValue(type.Value); x.WriteStringValue(type.Value);
} }
public void Accept(DBytes type, Utf8JsonWriter x) public void Accept(DBytes type, DefAssembly ass, Utf8JsonWriter x)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void Accept(DText type, Utf8JsonWriter x) public void Accept(DText type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStringValue(type.Value); x.WriteStringValue(type.GetText(ass.ExportTextTable, ass.NotConvertTextSet));
} }
public void Accept(DBean type, Utf8JsonWriter x) public void Accept(DBean type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStartObject(); x.WriteStartObject();
@ -108,51 +118,51 @@ namespace Luban.Job.Cfg.DataVisitors
} }
else else
{ {
d.Apply(this, x); d.Apply(this, ass, x);
} }
} }
x.WriteEndObject(); x.WriteEndObject();
} }
public void WriteList(List<DType> datas, Utf8JsonWriter x) public void WriteList(List<DType> datas, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStartArray(); x.WriteStartArray();
foreach (var d in datas) foreach (var d in datas)
{ {
d.Apply(this, x); d.Apply(this, ass, x);
} }
x.WriteEndArray(); x.WriteEndArray();
} }
public void Accept(DArray type, Utf8JsonWriter x) public void Accept(DArray type, DefAssembly ass, Utf8JsonWriter x)
{ {
WriteList(type.Datas, x); WriteList(type.Datas, ass, x);
} }
public void Accept(DList type, Utf8JsonWriter x) public void Accept(DList type, DefAssembly ass, Utf8JsonWriter x)
{ {
WriteList(type.Datas, x); WriteList(type.Datas, ass, x);
} }
public void Accept(DSet type, Utf8JsonWriter x) public void Accept(DSet type, DefAssembly ass, Utf8JsonWriter x)
{ {
WriteList(type.Datas, x); WriteList(type.Datas, ass, x);
} }
public void Accept(DMap type, Utf8JsonWriter x) public void Accept(DMap type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStartArray(); x.WriteStartArray();
foreach (var d in type.Datas) foreach (var d in type.Datas)
{ {
x.WriteStartArray(); x.WriteStartArray();
d.Key.Apply(this, x); d.Key.Apply(this, ass, x);
d.Value.Apply(this, x); d.Value.Apply(this, ass, x);
x.WriteEndArray(); x.WriteEndArray();
} }
x.WriteEndArray(); x.WriteEndArray();
} }
public void Accept(DVector2 type, Utf8JsonWriter x) public void Accept(DVector2 type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStartObject(); x.WriteStartObject();
x.WriteNumber("x", type.Value.X); x.WriteNumber("x", type.Value.X);
@ -160,7 +170,7 @@ namespace Luban.Job.Cfg.DataVisitors
x.WriteEndObject(); x.WriteEndObject();
} }
public void Accept(DVector3 type, Utf8JsonWriter x) public void Accept(DVector3 type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStartObject(); x.WriteStartObject();
x.WriteNumber("x", type.Value.X); x.WriteNumber("x", type.Value.X);
@ -169,7 +179,7 @@ namespace Luban.Job.Cfg.DataVisitors
x.WriteEndObject(); x.WriteEndObject();
} }
public void Accept(DVector4 type, Utf8JsonWriter x) public void Accept(DVector4 type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteStartObject(); x.WriteStartObject();
x.WriteNumber("x", type.Value.X); x.WriteNumber("x", type.Value.X);
@ -179,7 +189,7 @@ namespace Luban.Job.Cfg.DataVisitors
x.WriteEndObject(); x.WriteEndObject();
} }
public void Accept(DDateTime type, Utf8JsonWriter x) public void Accept(DDateTime type, DefAssembly ass, Utf8JsonWriter x)
{ {
x.WriteNumberValue(type.UnixTime); x.WriteNumberValue(type.UnixTime);
} }

View File

@ -7,52 +7,54 @@ using System.Text;
namespace Luban.Job.Cfg.DataVisitors namespace Luban.Job.Cfg.DataVisitors
{ {
class LuaExportor : IDataActionVisitor<StringBuilder> class LuaExportor : IDataActionVisitor<DefAssembly, StringBuilder>
{ {
public static LuaExportor Ins { get; } = new LuaExportor(); public static LuaExportor Ins { get; } = new LuaExportor();
public void ExportTableOne(DefTable t, List<DType> records, List<string> result) public void ExportTableOne(DefTable t, List<Record> records, List<string> result)
{ {
result.Add("return "); result.Add("return ");
var s = new StringBuilder(); var s = new StringBuilder();
Accept((DBean)records[0], s); Accept(records[0].Data, t.Assembly, s);
result.Add(s.ToString()); result.Add(s.ToString());
} }
public void ExportTableOneKeyMap(DefTable t, List<DType> records, List<string> result) public void ExportTableOneKeyMap(DefTable t, List<Record> records, List<string> result)
{ {
result.Add("return "); result.Add("return ");
result.Add("{"); result.Add("{");
var s = new StringBuilder(); var s = new StringBuilder();
var ks = new StringBuilder(); var ks = new StringBuilder();
foreach (DBean r in records) foreach (Record r in records)
{ {
DBean d = r.Data;
s.Clear(); s.Clear();
s.Append($"[{ToLuaCodeString(r.GetField(t.Index), ks)}] = "); s.Append($"[{ToLuaCodeString(d.GetField(t.Index), t.Assembly, ks)}] = ");
Accept(r, s); Accept(d, t.Assembly, s);
s.Append(','); s.Append(',');
result.Add(s.ToString()); result.Add(s.ToString());
} }
result.Add("}"); result.Add("}");
} }
public void ExportTableTwoKeyMap(DefTable t, List<DType> records, List<string> result) public void ExportTableTwoKeyMap(DefTable t, List<Record> records, List<string> result)
{ {
result.Add("return "); result.Add("return ");
result.Add("{"); result.Add("{");
var s = new StringBuilder(); var s = new StringBuilder();
var ks = new StringBuilder(); var ks = new StringBuilder();
foreach (var g in records.GroupBy(r => ((DBean)r).GetField(t.Index1))) foreach (var g in records.GroupBy(r => r.Data.GetField(t.Index1)))
{ {
result.Add($"[{ToLuaCodeString(g.Key, ks)}] ="); result.Add($"[{ToLuaCodeString(g.Key, t.Assembly, ks)}] =");
result.Add("{"); result.Add("{");
foreach (DBean r in g) foreach (Record r in g)
{ {
DBean d = r.Data;
s.Clear(); s.Clear();
s.Append($"[{ToLuaCodeString(r.GetField(t.Index2), ks)}] = "); s.Append($"[{ToLuaCodeString(d.GetField(t.Index2), t.Assembly, ks)}] = ");
Accept(r, s); Accept(d, t.Assembly, s);
s.Append(','); s.Append(',');
result.Add(s.ToString()); result.Add(s.ToString());
} }
@ -63,64 +65,64 @@ namespace Luban.Job.Cfg.DataVisitors
result.Add("}"); result.Add("}");
} }
private string ToLuaCodeString(DType data, StringBuilder b) private string ToLuaCodeString(DType data, DefAssembly ass, StringBuilder b)
{ {
b.Clear(); b.Clear();
data.Apply(this, b); data.Apply(this, ass, b);
return b.ToString(); return b.ToString();
} }
public void Accept(DBool type, StringBuilder line) public void Accept(DBool type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value ? "true" : "false"); line.Append(type.Value ? "true" : "false");
} }
public void Accept(DByte type, StringBuilder line) public void Accept(DByte type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DShort type, StringBuilder line) public void Accept(DShort type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DFshort type, StringBuilder line) public void Accept(DFshort type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DInt type, StringBuilder line) public void Accept(DInt type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DFint type, StringBuilder line) public void Accept(DFint type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DLong type, StringBuilder line) public void Accept(DLong type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DFlong type, StringBuilder line) public void Accept(DFlong type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DFloat type, StringBuilder line) public void Accept(DFloat type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DDouble type, StringBuilder line) public void Accept(DDouble type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
public void Accept(DEnum type, StringBuilder line) public void Accept(DEnum type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.Value); line.Append(type.Value);
} }
@ -130,22 +132,22 @@ namespace Luban.Job.Cfg.DataVisitors
return s.Replace("\\", "\\\\").Replace("'", "\\'"); return s.Replace("\\", "\\\\").Replace("'", "\\'");
} }
public void Accept(DString type, StringBuilder line) public void Accept(DString type, DefAssembly ass, StringBuilder line)
{ {
line.Append('\'').Append(EscapeString(type.Value)).Append('\''); line.Append('\'').Append(EscapeString(type.Value)).Append('\'');
} }
public void Accept(DBytes type, StringBuilder line) public void Accept(DBytes type, DefAssembly ass, StringBuilder line)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public void Accept(DText type, StringBuilder line) public void Accept(DText type, DefAssembly ass, StringBuilder line)
{ {
line.Append('\'').Append(EscapeString(type.Value)).Append('\''); line.Append('\'').Append(EscapeString(type.GetText(ass.ExportTextTable, ass.NotConvertTextSet))).Append('\'');
} }
public void Accept(DBean type, StringBuilder line) public void Accept(DBean type, DefAssembly ass, StringBuilder line)
{ {
var bean = type.Type; var bean = type.Type;
if (bean.IsAbstractType) if (bean.IsAbstractType)
@ -174,76 +176,76 @@ namespace Luban.Job.Cfg.DataVisitors
if (field != null) if (field != null)
{ {
line.Append(defField.Name).Append('='); line.Append(defField.Name).Append('=');
field.Apply(this, line); field.Apply(this, ass, line);
line.Append(','); line.Append(',');
} }
} }
line.Append("}"); line.Append("}");
} }
public void Accept(DArray type, StringBuilder line) public void Accept(DArray type, DefAssembly ass, StringBuilder line)
{ {
line.Append('{'); line.Append('{');
foreach (var d in type.Datas) foreach (var d in type.Datas)
{ {
d.Apply(this, line); d.Apply(this, ass, line);
line.Append(','); line.Append(',');
} }
line.Append('}'); line.Append('}');
} }
public void Accept(DList type, StringBuilder line) public void Accept(DList type, DefAssembly ass, StringBuilder line)
{ {
line.Append('{'); line.Append('{');
foreach (var d in type.Datas) foreach (var d in type.Datas)
{ {
d.Apply(this, line); d.Apply(this, ass, line);
line.Append(','); line.Append(',');
} }
line.Append('}'); line.Append('}');
} }
public void Accept(DSet type, StringBuilder line) public void Accept(DSet type, DefAssembly ass, StringBuilder line)
{ {
line.Append('{'); line.Append('{');
foreach (var d in type.Datas) foreach (var d in type.Datas)
{ {
d.Apply(this, line); d.Apply(this, ass, line);
line.Append(','); line.Append(',');
} }
line.Append('}'); line.Append('}');
} }
public void Accept(DMap type, StringBuilder line) public void Accept(DMap type, DefAssembly ass, StringBuilder line)
{ {
line.Append('{'); line.Append('{');
foreach ((var k, var v) in type.Datas) foreach ((var k, var v) in type.Datas)
{ {
line.Append('['); line.Append('[');
k.Apply(this, line); k.Apply(this, ass, line);
line.Append("]="); line.Append("]=");
v.Apply(this, line); v.Apply(this, ass, line);
line.Append(','); line.Append(',');
} }
line.Append('}'); line.Append('}');
} }
public void Accept(DVector2 type, StringBuilder line) public void Accept(DVector2 type, DefAssembly ass, StringBuilder line)
{ {
line.Append($"{{x={type.Value.X},y={type.Value.Y}}}"); line.Append($"{{x={type.Value.X},y={type.Value.Y}}}");
} }
public void Accept(DVector3 type, StringBuilder line) public void Accept(DVector3 type, DefAssembly ass, StringBuilder line)
{ {
line.Append($"{{x={type.Value.X},y={type.Value.Y},z={type.Value.Z}}}"); line.Append($"{{x={type.Value.X},y={type.Value.Y},z={type.Value.Z}}}");
} }
public void Accept(DVector4 type, StringBuilder line) public void Accept(DVector4 type, DefAssembly ass, StringBuilder line)
{ {
line.Append($"{{x={type.Value.X},y={type.Value.Y},z={type.Value.Z},w={type.Value.W}}}"); line.Append($"{{x={type.Value.X},y={type.Value.Y},z={type.Value.Z},w={type.Value.W}}}");
} }
public void Accept(DDateTime type, StringBuilder line) public void Accept(DDateTime type, DefAssembly ass, StringBuilder line)
{ {
line.Append(type.UnixTime); line.Append(type.UnixTime);
} }

View File

@ -0,0 +1,135 @@
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.i10n;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.DataVisitors
{
/// <summary>
/// 检查 相同key的text,原始值必须相同
/// </summary>
class TextValidatorVisitor : IDataActionVisitor<RawTextTable>
{
public static TextValidatorVisitor Ins { get; } = new TextValidatorVisitor();
public void Accept(DBool type, RawTextTable x)
{
}
public void Accept(DByte type, RawTextTable x)
{
}
public void Accept(DShort type, RawTextTable x)
{
}
public void Accept(DFshort type, RawTextTable x)
{
}
public void Accept(DInt type, RawTextTable x)
{
}
public void Accept(DFint type, RawTextTable x)
{
}
public void Accept(DLong type, RawTextTable x)
{
}
public void Accept(DFlong type, RawTextTable x)
{
}
public void Accept(DFloat type, RawTextTable x)
{
}
public void Accept(DDouble type, RawTextTable x)
{
}
public void Accept(DEnum type, RawTextTable x)
{
}
public void Accept(DString type, RawTextTable x)
{
}
public void Accept(DBytes type, RawTextTable x)
{
}
public void Accept(DText type, RawTextTable x)
{
x.AddText(ValidatorContext.CurrentVisitor.CurrentValidateRecord, type.Key, type.RawValue);
}
public void Accept(DBean type, RawTextTable x)
{
}
public void Accept(DArray type, RawTextTable x)
{
}
public void Accept(DList type, RawTextTable x)
{
}
public void Accept(DSet type, RawTextTable x)
{
}
public void Accept(DMap type, RawTextTable x)
{
}
public void Accept(DVector2 type, RawTextTable x)
{
}
public void Accept(DVector3 type, RawTextTable x)
{
}
public void Accept(DVector4 type, RawTextTable x)
{
}
public void Accept(DDateTime type, RawTextTable x)
{
}
}
}

View File

@ -75,7 +75,7 @@ namespace Luban.Job.Cfg.DataVisitors
public void Accept(DText type, StringBuilder x) public void Accept(DText type, StringBuilder x)
{ {
x.Append(type.Value); x.Append(type.Key).Append('|').Append(type.RawValue);
} }
public void Accept(DBean type, StringBuilder x) public void Accept(DBean type, StringBuilder x)

View File

@ -7,8 +7,6 @@ using System.Collections.Generic;
namespace Luban.Job.Cfg.DataVisitors namespace Luban.Job.Cfg.DataVisitors
{ {
public class ValidatorVisitor : IDataActionVisitor<DefAssembly> public class ValidatorVisitor : IDataActionVisitor<DefAssembly>
{ {
private readonly Stack<object> _path = new Stack<object>(); private readonly Stack<object> _path = new Stack<object>();
@ -17,33 +15,34 @@ namespace Luban.Job.Cfg.DataVisitors
public ValidatorContext Ctx { get; } public ValidatorContext Ctx { get; }
public DBean CurrentValidateRecord { get; private set; } public Record CurrentValidateRecord { get; set; }
public ValidatorVisitor(ValidatorContext ctx) public ValidatorVisitor(ValidatorContext ctx)
{ {
Ctx = ctx; Ctx = ctx;
} }
public void ValidateTable(DefTable table, List<DType> records) public void ValidateTable(DefTable table, List<Record> records)
{ {
DefAssembly ass = table.Assembly; DefAssembly ass = table.Assembly;
var keyIndex = table.IndexFieldIdIndex; var keyIndex = table.IndexFieldIdIndex;
foreach (DBean r in records) foreach (Record r in records)
{ {
CurrentValidateRecord = r; CurrentValidateRecord = r;
DBean data = r.Data;
_path.Clear(); _path.Clear();
_path.Push(table.FullName); _path.Push(table.FullName);
if (table.IsMapTable) if (table.IsMapTable)
{ {
_path.Push(r.Fields[keyIndex]); _path.Push(data.Fields[keyIndex]);
} }
else if (table.IsTwoKeyMapTable) else if (table.IsTwoKeyMapTable)
{ {
_path.Push(r.Fields[keyIndex]); _path.Push(data.Fields[keyIndex]);
_path.Push(r.Fields[table.IndexFieldIdIndex2]); _path.Push(data.Fields[table.IndexFieldIdIndex2]);
} }
Accept(r, ass); Accept(data, ass);
} }
} }

View File

@ -1,16 +1,37 @@
using Luban.Job.Cfg.DataVisitors; using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.i10n;
using System.Collections.Generic;
namespace Luban.Job.Cfg.Datas namespace Luban.Job.Cfg.Datas
{ {
public class DText : DType<string> public class DText : DType
{ {
public string Key { get; } public string Key { get; }
public DText(string key, string x) : base(x) private readonly string _rawValue;
public string RawValue => _rawValue;
public DText(string key, string x)
{ {
Key = key; Key = key;
_rawValue = x;
}
System.Console.WriteLine("== text. key:{0} text:{1}", key, x); public string GetText(TextTable stringTable, NotConvertTextSet notConvertKeys)
{
if (stringTable != null)
{
if (stringTable.TryGetText(Key, out var text))
{
return text;
}
else if (notConvertKeys != null)
{
notConvertKeys.Add(Key, _rawValue);
}
}
return _rawValue;
} }
public override void Apply<T>(IDataActionVisitor<T> visitor, T x) public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
@ -35,12 +56,12 @@ namespace Luban.Job.Cfg.Datas
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return obj is DText o && o.Value == this.Value; return obj is DText o && o._rawValue == this._rawValue && o.Key == this.Key;
} }
public override int GetHashCode() public override int GetHashCode()
{ {
return Value.GetHashCode(); return _rawValue.GetHashCode();
} }
} }
} }

View File

@ -20,11 +20,6 @@ namespace Luban.Job.Cfg.Datas
this.Apply(ToStringVisitor.Ins, s); this.Apply(ToStringVisitor.Ins, s);
return s.ToString(); return s.ToString();
} }
/// <summary>
/// 从哪儿创建的. 一般来说会保存它的源文件
/// </summary>
public object Source { get; set; }
} }
public abstract class DType<T> : DType public abstract class DType<T> : DType

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.Datas
{
public class Record
{
public DBean Data { get; }
public string Source { get; }
public Record(DBean data, string source)
{
Data = data;
Source = source;
}
}
}

View File

@ -1,5 +1,6 @@
using Luban.Config.Common.RawDefs; using Luban.Config.Common.RawDefs;
using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.i10n;
using Luban.Job.Cfg.TypeVisitors; using Luban.Job.Cfg.TypeVisitors;
using Luban.Job.Common.Defs; using Luban.Job.Common.Defs;
using Luban.Server.Common; using Luban.Server.Common;
@ -34,12 +35,16 @@ namespace Luban.Job.Cfg.Defs
private readonly List<Service> _cfgServices = new List<Service>(); private readonly List<Service> _cfgServices = new List<Service>();
private readonly ConcurrentDictionary<string, List<DType>> _recordsByTables = new ConcurrentDictionary<string, List<DType>>(); private readonly ConcurrentDictionary<string, List<Record>> _recordsByTables = new();
private readonly ConcurrentDictionary<string, Dictionary<DType, DBean>> _recordsMapByTables = new ConcurrentDictionary<string, Dictionary<DType, DBean>>(); private readonly ConcurrentDictionary<string, Dictionary<DType, Record>> _recordsMapByTables = new();
public Dictionary<string, DefTable> CfgTables { get; } = new Dictionary<string, DefTable>(); public Dictionary<string, DefTable> CfgTables { get; } = new Dictionary<string, DefTable>();
private readonly ConcurrentDictionary<string, string> _texts = new ConcurrentDictionary<string, string>(); public RawTextTable RawTextTable { get; } = new RawTextTable();
public TextTable ExportTextTable { get; } = new TextTable();
public NotConvertTextSet NotConvertTextSet { get; } = new NotConvertTextSet();
public void AddCfgTable(DefTable table) public void AddCfgTable(DefTable table)
{ {
@ -54,22 +59,22 @@ namespace Luban.Job.Cfg.Defs
return CfgTables.TryGetValue(name, out var t) ? t : null; return CfgTables.TryGetValue(name, out var t) ? t : null;
} }
public void AddDataTable(DefTable table, List<DType> records) public void AddDataTable(DefTable table, List<Record> records)
{ {
_recordsByTables[table.FullName] = records; _recordsByTables[table.FullName] = records;
} }
public void SetDataTableMap(DefTable table, Dictionary<DType, DBean> recordMap) public void SetDataTableMap(DefTable table, Dictionary<DType, Record> recordMap)
{ {
_recordsMapByTables[table.FullName] = recordMap; _recordsMapByTables[table.FullName] = recordMap;
} }
public List<DType> GetTableDataList(DefTable table) public List<Record> GetTableDataList(DefTable table)
{ {
return _recordsByTables[table.FullName]; return _recordsByTables[table.FullName];
} }
public Dictionary<DType, DBean> GetTableDataMap(DefTable table) public Dictionary<DType, Record> GetTableDataMap(DefTable table)
{ {
return _recordsMapByTables[table.FullName]; return _recordsMapByTables[table.FullName];
} }
@ -111,22 +116,6 @@ namespace Luban.Job.Cfg.Defs
return refTypes.Values.ToList(); return refTypes.Values.ToList();
} }
public void AddText(string key, string text)
{
if (key == null || text == null)
{
throw new Exception("text的key或text属性不能为null");
}
if (key == "" && text != "")
{
throw new InvalidExcelDataException($"text key为空, 但text:{text}不为空");
}
if (!_texts.TryAdd(key, text) && _texts[key] != text)
{
throw new Exception($"text key:{key} 出现多次,但值不相同. 当前:{text} 之前:{_texts[key]}");
}
}
public void Load(string outputService, Defines defines, RemoteAgent agent) public void Load(string outputService, Defines defines, RemoteAgent agent)
{ {
this.Agent = agent; this.Agent = agent;

View File

@ -1089,26 +1089,27 @@ class Vector4:
return index >= 0 ? file[(index + 1)..] : file; return index >= 0 ? file[(index + 1)..] : file;
} }
private List<DType> LoadCfgRecords(DefTable table, string originFile, string sheetName, byte[] content, bool multiRecord, bool exportTestData) private List<Record> LoadCfgRecords(DefTable table, string originFile, string sheetName, byte[] content, bool multiRecord, bool exportTestData)
{ {
// (md5,sheet,multiRecord,exportTestData) -> (valuetype, List<(datas)>) // (md5,sheet,multiRecord,exportTestData) -> (valuetype, List<(datas)>)
var dataSourc = DataSourceFactory.Create(originFile, sheetName, new MemoryStream(content), exportTestData); var dataSource = DataSourceFactory.Create(originFile, sheetName, new MemoryStream(content), exportTestData);
try try
{ {
List<DType> datas; List<DType> datas;
if (multiRecord) if (multiRecord)
{ {
datas = dataSourc.ReadMulti(table.ValueTType); datas = dataSource.ReadMulti(table.ValueTType);
} }
else else
{ {
datas = new List<DType> { dataSourc.ReadOne(table.ValueTType) }; datas = new List<DType> { dataSource.ReadOne(table.ValueTType) };
} }
var records = new List<Record>(datas.Count);
foreach (var data in datas) foreach (var data in datas)
{ {
data.Source = originFile; records.Add(new Record((DBean)data, originFile));
} }
return datas; return records;
} }
catch (Exception e) catch (Exception e)
{ {
@ -1163,7 +1164,7 @@ class Vector4:
public async Task LoadTableAsync(RemoteAgent agent, DefTable table, string dataDir, bool exportTestData) public async Task LoadTableAsync(RemoteAgent agent, DefTable table, string dataDir, bool exportTestData)
{ {
var tasks = new List<Task<List<DType>>>(); var tasks = new List<Task<List<Record>>>();
var inputFiles = await CollectInputFilesAsync(agent, table, dataDir); var inputFiles = await CollectInputFilesAsync(agent, table, dataDir);
@ -1194,7 +1195,7 @@ class Vector4:
})); }));
} }
var records = new List<DType>(tasks.Count); var records = new List<Record>(tasks.Count);
foreach (var task in tasks) foreach (var task in tasks)
{ {
records.AddRange(await task); records.AddRange(await task);
@ -1207,14 +1208,14 @@ class Vector4:
s_logger.Trace("table:{name} record num:{num}", table.FullName, records.Count); s_logger.Trace("table:{name} record num:{num}", table.FullName, records.Count);
} }
private byte[] ToOutputData(DefTable table, List<DType> records, string dataType) private byte[] ToOutputData(DefTable table, List<Record> records, string dataType)
{ {
switch (dataType) switch (dataType)
{ {
case "data_bin": case "data_bin":
{ {
var buf = ThreadLocalTemporalByteBufPool.Alloc(1024 * 1024); var buf = ThreadLocalTemporalByteBufPool.Alloc(1024 * 1024);
BinaryExportor.Ins.WriteList(records, buf); BinaryExportor.Ins.WriteList(records, table.Assembly, buf);
var bytes = buf.CopyData(); var bytes = buf.CopyData();
ThreadLocalTemporalByteBufPool.Free(buf); ThreadLocalTemporalByteBufPool.Free(buf);
return bytes; return bytes;
@ -1228,7 +1229,7 @@ class Vector4:
SkipValidation = false, SkipValidation = false,
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All), Encoder = System.Text.Encodings.Web.JavaScriptEncoder.Create(System.Text.Unicode.UnicodeRanges.All),
}); });
JsonExportor.Ins.WriteList(records, jsonWriter); JsonExportor.Ins.WriteList(records, table.Assembly, jsonWriter);
jsonWriter.Flush(); jsonWriter.Flush();
return DataUtil.StreamToBytes(ss); return DataUtil.StreamToBytes(ss);
} }
@ -1267,12 +1268,12 @@ class Vector4:
} }
} }
private List<ResourceInfo> ExportResourceList(List<DType> records) private List<ResourceInfo> ExportResourceList(List<Record> records)
{ {
var resList = new List<ResourceInfo>(); var resList = new List<ResourceInfo>();
foreach (DBean res in records) foreach (Record res in records)
{ {
ResourceExportor.Ins.Accept(res, null, resList); ResourceExportor.Ins.Accept(res.Data, null, resList);
} }
return resList; return resList;
} }

View File

@ -291,7 +291,7 @@ namespace Luban.Job.Cfg.TypeVisitors
} }
string key = ParseString(x.Read(x.NamedMode)); string key = ParseString(x.Read(x.NamedMode));
string text = ParseString(x.Read(x.NamedMode)); string text = ParseString(x.Read(x.NamedMode));
ass.AddText(key, text); DataUtil.ValidateText(key, text);
return new DText(key, text); return new DText(key, text);
} }

View File

@ -160,7 +160,7 @@ namespace Luban.Job.Cfg.TypeVisitors
} }
else else
{ {
ExcelStream stream = row.GetColumn(f.Name, sep); ExcelStream stream = row.GetColumn(f.Name, sep, !f.CType.Apply(IsMultiData.Ins));
try try
{ {
list.Add(f.CType.Apply(ExcelDataCreator.Ins, f.Remapper, stream, (DefAssembly)bean.AssemblyBase)); list.Add(f.CType.Apply(ExcelDataCreator.Ins, f.Remapper, stream, (DefAssembly)bean.AssemblyBase));
@ -180,7 +180,7 @@ namespace Luban.Job.Cfg.TypeVisitors
var originBean = (DefBean)type.Bean; var originBean = (DefBean)type.Bean;
if (originBean.IsAbstractType) if (originBean.IsAbstractType)
{ {
string subType = row.GetColumn(DefBean.TYPE_NAME_KEY, null).Read().ToString().Trim(); string subType = row.GetColumn(DefBean.TYPE_NAME_KEY, null, true).Read().ToString().Trim();
if (subType.ToLower() == "null") if (subType.ToLower() == "null")
{ {
return new DBean(originBean, null, null); return new DBean(originBean, null, null);

View File

@ -100,7 +100,7 @@ namespace Luban.Job.Cfg.TypeVisitors
throw new Exception("text text不是字符串"); throw new Exception("text text不是字符串");
} }
ass.AddText(key, text); DataUtil.ValidateText(key, text);
return new DText(key, text); return new DText(key, text);
} }

View File

@ -140,7 +140,7 @@ namespace Luban.Job.Cfg.TypeVisitors
{ {
throw new Exception("text缺失text属性"); throw new Exception("text缺失text属性");
} }
ass.AddText(key, text); DataUtil.ValidateText(key, text);
return new DText(key, text); return new DText(key, text);
} }

View File

@ -84,7 +84,7 @@ namespace Luban.Job.Cfg.TypeVisitors
{ {
var key = x.Element("key").Value; var key = x.Element("key").Value;
var text = x.Element("text").Value; var text = x.Element("text").Value;
ass.AddText(key, text); DataUtil.ValidateText(key, text);
return new DText(key, text); return new DText(key, text);
} }
@ -102,15 +102,11 @@ namespace Luban.Job.Cfg.TypeVisitors
} }
var fullName = TypeUtil.MakeFullName(bean.Namespace, subType); var fullName = TypeUtil.MakeFullName(bean.Namespace, subType);
var defType = (DefBean)bean.GetNotAbstractChildType(subType); var defType = (DefBean)bean.GetNotAbstractChildType(subType);
if (defType == null)
{
throw new Exception($"type:{fullName} 不是合法类型");
}
//if (defType.IsAbstractType) //if (defType.IsAbstractType)
//{ //{
// throw new Exception($"type:{fullName} 是抽象类. 不能创建实例"); // throw new Exception($"type:{fullName} 是抽象类. 不能创建实例");
//} //}
implBean = defType; implBean = defType ?? throw new Exception($"type:{fullName} 不是合法类型");
} }
else else
{ {

View File

@ -59,11 +59,6 @@ namespace Luban.Job.Cfg.Utils
return bytes; return bytes;
} }
public static string GetSourceFile(DType data)
{
return (string)data.Source;
}
public static string UnEscapeString(string s) public static string UnEscapeString(string s)
{ {
if (s == "null" || s == "\"\"") if (s == "null" || s == "\"\"")
@ -83,6 +78,18 @@ namespace Luban.Job.Cfg.Utils
return (keyAndText[0], keyAndText[1]); return (keyAndText[0], keyAndText[1]);
} }
public static void ValidateText(string key, string text)
{
if (key == null || text == null)
{
throw new Exception("text的key或text属性不能为null");
}
if (key == "" && text != "")
{
throw new Exception($"text key为空, 但text:{text}不为空");
}
}
//public static string Data2String(DType data) //public static string Data2String(DType data)
//{ //{
// var s = new StringBuilder(); // var s = new StringBuilder();

View File

@ -69,6 +69,7 @@ namespace Luban.Job.Cfg
{ {
var records = t.Assembly.GetTableDataList(t); var records = t.Assembly.GetTableDataList(t);
ValidateTableModeIndex(t, records); ValidateTableModeIndex(t, records);
})); }));
} }
await Task.WhenAll(tasks); await Task.WhenAll(tasks);
@ -86,6 +87,7 @@ namespace Luban.Job.Cfg
{ {
CurrentVisitor = visitor; CurrentVisitor = visitor;
visitor.ValidateTable(t, records); visitor.ValidateTable(t, records);
ValidateText(t, records);
} }
finally finally
{ {
@ -102,6 +104,16 @@ namespace Luban.Job.Cfg
} }
} }
private void ValidateText(DefTable table, List<Record> records)
{
foreach (var r in records)
{
CurrentVisitor.CurrentValidateRecord = r;
r.Data.Apply(TextValidatorVisitor.Ins, this.Assembly.RawTextTable);
}
CurrentVisitor.CurrentValidateRecord = null;
}
private async Task ValidatePaths() private async Task ValidatePaths()
{ {
var queryFiles = new HashSet<string>(_pathQuerys.Count * 2); var queryFiles = new HashSet<string>(_pathQuerys.Count * 2);
@ -160,9 +172,9 @@ namespace Luban.Job.Cfg
} }
} }
private void ValidateTableModeIndex(DefTable table, List<DType> records) private void ValidateTableModeIndex(DefTable table, List<Record> records)
{ {
var recordMap = new Dictionary<DType, DBean>(); var recordMap = new Dictionary<DType, Record>();
switch (table.Mode) switch (table.Mode)
{ {
@ -176,14 +188,14 @@ namespace Luban.Job.Cfg
} }
case ETableMode.MAP: case ETableMode.MAP:
{ {
foreach (DBean r in records) foreach (Record r in records)
{ {
DType key = r.Fields[table.IndexFieldIdIndex]; DType key = r.Data.Fields[table.IndexFieldIdIndex];
if (!recordMap.TryAdd(key, r)) if (!recordMap.TryAdd(key, r))
{ {
throw new Exception($@"配置表 {table.FullName} 主键字段:{table.Index} 主键值:{key} 重复. throw new Exception($@"配置表 {table.FullName} 主键字段:{table.Index} 主键值:{key} 重复.
1 :{DataUtil.GetSourceFile(r)} 1 :{r.Source}
2 :{DataUtil.GetSourceFile(recordMap[key])} 2 :{recordMap[key].Source}
"); ");
} }
@ -192,16 +204,16 @@ namespace Luban.Job.Cfg
} }
case ETableMode.BMAP: case ETableMode.BMAP:
{ {
var twoKeyMap = new Dictionary<(DType, DType), DBean>(); var twoKeyMap = new Dictionary<(DType, DType), Record>();
foreach (DBean r in records) foreach (Record r in records)
{ {
DType key1 = r.Fields[table.IndexFieldIdIndex1]; DType key1 = r.Data.Fields[table.IndexFieldIdIndex1];
DType key2 = r.Fields[table.IndexFieldIdIndex2]; DType key2 = r.Data.Fields[table.IndexFieldIdIndex2];
if (!twoKeyMap.TryAdd((key1, key2), r)) if (!twoKeyMap.TryAdd((key1, key2), r))
{ {
throw new Exception($@"配置表 {table.FullName} 主键字段:{table.Index} 主键值:({key1},{key2})重复. throw new Exception($@"配置表 {table.FullName} 主键字段:{table.Index} 主键值:({key1},{key2})重复.
1 :{DataUtil.GetSourceFile(r)} 1 :{r.Source}
2 :{DataUtil.GetSourceFile(twoKeyMap[(key1, key2)])} 2 :{twoKeyMap[(key1, key2)].Source}
"); ");
} }
// 目前不支持 双key索引检查,但支持主key索引检查. // 目前不支持 双key索引检查,但支持主key索引检查.

View File

@ -175,7 +175,7 @@ namespace Luban.Job.Cfg.Validators
return; return;
} }
string source = DataUtil.GetSourceFile(ValidatorContext.CurrentVisitor.CurrentValidateRecord); string source = ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
object finalPaths = PathPattern.CalcFinalPath(value); object finalPaths = PathPattern.CalcFinalPath(value);
if (finalPaths == null) if (finalPaths == null)
{ {

View File

@ -134,7 +134,7 @@ namespace Luban.Job.Cfg.Validators
return true; return true;
} }
public string Source => DataUtil.GetSourceFile(ValidatorContext.CurrentVisitor.CurrentValidateRecord); public string Source => ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
public void Validate(ValidatorContext ctx, DType data, bool nullable) public void Validate(ValidatorContext ctx, DType data, bool nullable)
{ {

View File

@ -72,7 +72,7 @@ namespace Luban.Job.Cfg.Validators
actualTable = table; actualTable = table;
} }
DefTable ct = assembly.GetCfgTable(actualTable); DefTable ct = assembly.GetCfgTable(actualTable);
string source = DataUtil.GetSourceFile(ValidatorContext.CurrentVisitor.CurrentValidateRecord); string source = ValidatorContext.CurrentVisitor.CurrentValidateRecord.Source;
assembly.Agent.Error("记录 {0} = {1} (来自文件:{2}) 在引用表:{3} 中不存在", ValidatorContext.CurrentRecordPath, key, source, table); assembly.Agent.Error("记录 {0} = {1} (来自文件:{2}) 在引用表:{3} 中不存在", ValidatorContext.CurrentRecordPath, key, source, table);
} }
} }

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.i10n
{
public class NotConvertTextSet
{
private readonly ConcurrentDictionary<string, string> _notConvertTexts = new();
public void Add(string key, string text)
{
_notConvertTexts.TryAdd(key, text);
}
}
}

View File

@ -0,0 +1,48 @@
using Luban.Job.Cfg.Datas;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.i10n
{
public class RawTextTable
{
private readonly ConcurrentDictionary<string, (Record Record, string Text)> _texts = new();
public void AddText(Record record, string key, string text)
{
if (key == null || text == null)
{
throw new Exception("text的key或text属性不能为null");
}
if (key == "" && text != "")
{
throw new Exception($"text key为空, 但text:{text}不为空");
}
if (!_texts.TryAdd(key, (record, text)) && _texts[key].Text != text)
{
throw new Exception($@"text key:{key} 出现多次,但值不相同.
:{text} :{record.Source}
:{_texts[key].Text} :{_texts[key].Record.Source}");
}
}
public bool TryGetText(string key, out string text)
{
if (_texts.TryGetValue(key, out var e))
{
text = e.Text;
return true;
}
else
{
text = null;
return false;
}
}
}
}

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Luban.Job.Cfg.i10n
{
public class TextTable
{
private readonly Dictionary<string, string> _key2Texts = new();
public TextTable()
{
_key2Texts.Add("test/a", "这是本地化数据 test/a");
_key2Texts.Add("name", "这是本地化数据 name");
}
public void AddText(string key, string text)
{
if (!_key2Texts.TryAdd(key, text))
{
throw new Exception($"text key:{key} 重复");
}
}
public bool TryGetText(string key, out string text)
{
return _key2Texts.TryGetValue(key, out text);
}
}
}