【优化】优化LubanAssistant保存,只保存改变的记录。优化记录显示顺序,如果key为int和long类型,按从小到大排序,而不是按字符串顺序排序。

main
walon 2021-10-22 14:33:12 +08:00
parent fb55a7a4c6
commit 5665e76299
14 changed files with 186 additions and 35 deletions

View File

@ -1,4 +1,5 @@
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using System.Collections.Generic;
@ -17,6 +18,16 @@ namespace Luban.Job.Cfg.Datas
this.Datas = datas;
}
public override bool Equals(object obj)
{
return obj is DArray d && DataUtil.IsCollectionEqual(Datas, d.Datas);
}
public override int GetHashCode()
{
throw new System.NotSupportedException();
}
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{
visitor.Accept(this, x);

View File

@ -1,5 +1,6 @@
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.Utils;
using System.Collections.Generic;
namespace Luban.Job.Cfg.Datas
@ -21,6 +22,16 @@ namespace Luban.Job.Cfg.Datas
this.Fields = fields;
}
public override bool Equals(object obj)
{
return obj is DBean d && string.Equals(ImplType?.FullName, d.ImplType?.FullName) && DataUtil.IsCollectionEqual(Fields, d.Fields);
}
public override int GetHashCode()
{
throw new System.NotSupportedException();
}
public DType GetField(string fieldName)
{
if (ImplType.TryGetField(fieldName, out var _, out var findex))

View File

@ -11,6 +11,16 @@ namespace Luban.Job.Cfg.Datas
{
}
public override bool Equals(object obj)
{
return obj is DBytes d && System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(Value, d.Value);
}
public override int GetHashCode()
{
throw new System.NotSupportedException();
}
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{
visitor.Accept(this, x);

View File

@ -20,6 +20,16 @@ namespace Luban.Job.Cfg.Datas
this._localTime = (int)new DateTimeOffset(time).ToUnixTimeSeconds();
}
public override bool Equals(object obj)
{
return obj is DDateTime d && Time == d.Time;
}
public override int GetHashCode()
{
return _localTime.GetHashCode();
}
public int GetUnixTime(TimeZoneInfo asTimeZone)
{
if (asTimeZone == null || asTimeZone == TimeZoneInfo.Local)

View File

@ -17,6 +17,16 @@ namespace Luban.Job.Cfg.Datas
{
}
public override bool Equals(object obj)
{
return obj is DFshort d && Value == d.Value;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{
visitor.Accept(this, x);
@ -36,15 +46,5 @@ namespace Luban.Job.Cfg.Datas
{
return visitor.Accept(this, x);
}
public override bool Equals(object obj)
{
return obj is DFshort o && o.Value == this.Value;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
}
}

View File

@ -1,4 +1,5 @@
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using System.Collections.Generic;
@ -17,6 +18,17 @@ namespace Luban.Job.Cfg.Datas
this.Datas = datas;
}
public override bool Equals(object obj)
{
return obj is DList d && DataUtil.IsCollectionEqual(Datas, d.Datas);
}
public override int GetHashCode()
{
throw new System.NotSupportedException();
}
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{
visitor.Accept(this, x);

View File

@ -1,7 +1,9 @@
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Luban.Job.Cfg.Datas
{
@ -27,6 +29,16 @@ namespace Luban.Job.Cfg.Datas
}
}
public override bool Equals(object obj)
{
return obj is DMap d && Datas.Count == d.Datas.Count && Datas.All(e => d.Datas.TryGetValue(e.Key, out var v) && object.Equals(e.Value, v));
}
public override int GetHashCode()
{
throw new System.NotSupportedException();
}
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{
visitor.Accept(this, x);

View File

@ -1,4 +1,5 @@
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using System;
using System.Collections.Generic;
@ -27,6 +28,16 @@ namespace Luban.Job.Cfg.Datas
}
}
public override bool Equals(object obj)
{
return obj is DList d && DataUtil.IsCollectionEqual(Datas, d.Datas);
}
public override int GetHashCode()
{
throw new System.NotSupportedException();
}
public override void Apply<T>(IDataActionVisitor<T> visitor, T x)
{
visitor.Accept(this, x);

View File

@ -157,6 +157,23 @@ namespace Luban.Job.Cfg.Utils
default: return "";
}
}
public static bool IsCollectionEqual(List<DType> a, List<DType> b)
{
if (a.Count == b.Count)
{
for (int i = 0, n = a.Count; i < n; i++)
{
if (!object.Equals(a[i], b[i]))
{
return false;
}
}
return true;
}
return false;
}
//public static string Data2String(DType data)
//{
// var s = new StringBuilder();

View File

@ -114,6 +114,7 @@ namespace LubanAssistant
var tableDataInfo = LastLoadTableData = await DataLoaderUtil.LoadTableDataAsync(RootDefineFile, InputDataDir, rawSheet.TableName);
var title = ExcelUtil.ParseTitles(sheet);
ExcelUtil.FillRecords(sheet, rawSheet.TitleRowCount, title, tableDataInfo);
MessageBox.Show("加载成功");
}
catch (Exception e)
{
@ -158,7 +159,7 @@ namespace LubanAssistant
}
}
private void SaveRecords(Action<Worksheet, int, TableDataInfo, DefTable, Title> saveTask)
private void SaveRecords(Func<Worksheet, int, TableDataInfo, DefTable, Title, Task> saveTask)
{
Worksheet sheet = Globals.LubanAssistant.Application.ActiveSheet;
@ -181,7 +182,7 @@ namespace LubanAssistant
var tableDef = await DataLoaderUtil.LoadTableDefAsync(RootDefineFile, InputDataDir, tableName);
var title = ExcelUtil.ParseTitles(sheet);
saveTask(sheet, rawSheet.TitleRowCount, LastLoadTableData, tableDef, title);
await saveTask(sheet, rawSheet.TitleRowCount, LastLoadTableData, tableDef, title);
}
catch (Exception e)
{
@ -192,15 +193,16 @@ namespace LubanAssistant
private void BtnSaveAllClick(object sender, RibbonControlEventArgs e)
{
SaveRecords((Worksheet sheet, int titleRowNum, TableDataInfo tableDataInfo, DefTable defTable, Title title) =>
SaveRecords(async (Worksheet sheet, int titleRowNum, TableDataInfo tableDataInfo, DefTable defTable, Title title) =>
{
int usedRowNum = sheet.UsedRange.Rows.Count;
int firstDataRowNum = titleRowNum + 2;
if (firstDataRowNum <= usedRowNum)
{
var newRecords = ExcelUtil.LoadRecordsInRange(defTable, sheet, title, (sheet.Range[$"A{firstDataRowNum}:A{usedRowNum}"]).EntireRow);
ExcelUtil.SaveRecords(InputDataDir, defTable, newRecords);
await ExcelUtil.SaveRecordsAsync(InputDataDir, defTable, GetModifyRecords(LastLoadTableData, newRecords));
CleanRemovedRecordFiles(LastLoadTableData, newRecords);
MessageBox.Show("保存成功");
}
else
{
@ -209,6 +211,15 @@ namespace LubanAssistant
});
}
private List<Record> GetModifyRecords(TableDataInfo lastTableDataInfo, List<Record> newRecords)
{
string index = lastTableDataInfo.Table.IndexField.Name;
var oldRecordDic = lastTableDataInfo.MainRecords.ToDictionary(r => r.Data.GetField(index));
var newRecordDic = newRecords.ToDictionary(r => r.Data.GetField(index));
return newRecordDic.Where(e => !oldRecordDic.TryGetValue(e.Key, out var r) || !object.Equals(e.Value.Data, r.Data)).Select(e => e.Value).ToList();
}
private void CleanRemovedRecordFiles(TableDataInfo lastTableDataInfo, List<Record> newRecords)
{
string index = lastTableDataInfo.Table.IndexField.Name;
@ -241,13 +252,14 @@ namespace LubanAssistant
MessageBox.Show("没有选中的行");
return;
}
SaveRecords((Worksheet sheet, int titleRowNum, TableDataInfo tableDataInfo, DefTable defTable, Title title) =>
SaveRecords(async (Worksheet sheet, int titleRowNum, TableDataInfo tableDataInfo, DefTable defTable, Title title) =>
{
int usedRowNum = sheet.UsedRange.Rows.Count;
if (titleRowNum + 1 < usedRowNum)
{
var newRecords = ExcelUtil.LoadRecordsInRange(defTable, sheet, title, selectRange.EntireRow);
ExcelUtil.SaveRecords(InputDataDir, defTable, newRecords);
await ExcelUtil.SaveRecordsAsync(InputDataDir, defTable, GetModifyRecords(LastLoadTableData, newRecords));
MessageBox.Show("保存成功");
}
else
{

View File

@ -1,9 +1,11 @@
using Luban.Job.Cfg.DataExporters;
using Luban.Common.Utils;
using Luban.Job.Cfg.DataExporters;
using Luban.Job.Cfg.Datas;
using Luban.Job.Cfg.DataSources.Excel;
using Luban.Job.Cfg.DataVisitors;
using Luban.Job.Cfg.Defs;
using Luban.Job.Cfg.Utils;
using Luban.Job.Common.Types;
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
@ -150,9 +152,28 @@ namespace LubanAssistant
//int nextRowIndex = titleRowNum + 2;
// 对于 int和long类型记录按值排序
var records = tableDataInfo.MainRecords;
DefField keyField = tableDataInfo.Table.IndexField;
if (keyField != null && (keyField.CType is TInt || keyField.CType is TLong))
{
string keyFieldName = keyField.Name;
records.Sort((a, b) =>
{
DType keya = a.Data.GetField(keyFieldName);
DType keyb = b.Data.GetField(keyFieldName);
switch (keya)
{
case DInt ai: return ai.Value.CompareTo((keyb as DInt).Value);
case DLong al: return al.Value.CompareTo((keyb as DLong).Value);
default: throw new NotSupportedException();
}
});
}
int totalRowCount = 0;
var dataRangeArray = new List<object[]>();
foreach (var rec in tableDataInfo.MainRecords)
foreach (var rec in records)
{
var fillVisitor = new FillSheetVisitor(dataRangeArray, title.ToIndex + 1, totalRowCount);
totalRowCount += rec.Data.Apply(fillVisitor, title);
@ -168,7 +189,7 @@ namespace LubanAssistant
}
}
Range recordFillRange = sheet.Range[sheet.Cells[titleRowNum + 2, 1], sheet.Cells[titleRowNum + dataRangeArray.Count, title.ToIndex + 1]];
Range recordFillRange = sheet.Range[sheet.Cells[titleRowNum + 2, 1], sheet.Cells[titleRowNum + 1 + dataRangeArray.Count, title.ToIndex + 1]];
recordFillRange.Value = resultDataRangeArray;
}
@ -181,11 +202,16 @@ namespace LubanAssistant
return excelSource.ReadMulti(table.ValueTType);
}
public static void SaveRecords(string inputDataDir, DefTable table, List<Record> records)
public static async Task SaveRecordsAsync(string inputDataDir, DefTable table, List<Record> records)
{
var recordOutputDir = Path.Combine(inputDataDir, table.InputFiles[0]);
string index = table.IndexField.Name;
var saveRecordTasks = new List<Task>();
foreach (var r in records)
{
saveRecordTasks.Add(Task.Run(async () =>
{
var ss = new MemoryStream();
var jsonWriter = new Utf8JsonWriter(ss, new JsonWriterOptions()
@ -197,11 +223,25 @@ namespace LubanAssistant
RawJsonExportor.Ins.Accept(r.Data, jsonWriter);
jsonWriter.Flush();
byte[] resultBytes = DataUtil.StreamToBytes(ss);
var key = r.Data.GetField(index);
var fileName = $"{key.Apply(ToStringVisitor.Ins)}.json";
File.WriteAllBytes(Path.Combine(recordOutputDir, fileName), DataUtil.StreamToBytes(ss));
// 只有文件内容改变才重新加载
string fileFullPath = Path.Combine(recordOutputDir, fileName);
if (File.Exists(fileFullPath))
{
var oldBytes = await FileUtil.ReadAllBytesAsync(fileFullPath);
if (System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(resultBytes, oldBytes))
{
return;
}
}
await FileUtil.SaveFileAsync(recordOutputDir, fileName, resultBytes);
}));
}
await Task.WhenAll(saveRecordTasks);
}
//public static void FillRecord(Worksheet sheet, ref int nextRowIndex, Title title, Record record)
//{

View File

@ -24,5 +24,10 @@ namespace Luban.Job.Cfg.Datas
{
Value = value;
}
public override int GetHashCode()
{
return Value.GetHashCode();
}
}
}

View File

@ -127,7 +127,7 @@ namespace LubanAssistant
{
if (string.IsNullOrEmpty(sep) && type.Type.ElementType.Apply(IsNotSepTypeVisitor.Ins))
{
sep = ",";
sep = ";";
}
return string.Join(sep, type.Datas.Select(d => d.Apply(this, sep)));
}