-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathExcelConfigSet.cs
390 lines (325 loc) · 13 KB
/
ExcelConfigSet.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
using System.Collections;
using ProtoBuf;
using System.Collections.Generic;
using System;
using System.IO;
using xresloader.Protobuf;
namespace xresloader {
public class ExcelConfigSet {
private string fileName;
private string protocol;
private DynamicFactory factory;
private List<DynamicMessage> datas = new List<DynamicMessage>();
public List<DynamicMessage> Datas { get { return datas; } }
public struct Key {
public object[] keys;
public int Size { get { return keys == null ? 0 : keys.Length; } }
public Key(params object[] collection) {
keys = collection;
}
public Key(object data) {
keys = new object[1] { data };
}
public override int GetHashCode() {
int ret = 0;
for (int i = 0; i < keys.Length; ++i) {
ret ^= keys[i].GetHashCode();
}
return ret;
}
public bool Equals(Key obj) {
if (Size != obj.Size) {
return false;
}
for (int i = 0; i < keys.Length; ++i) {
if (!keys[i].Equals(obj.keys[i])) {
return false;
}
}
return true;
}
public override bool Equals(object obj) {
if (!(obj is Key)) {
return false;
}
return Equals((Key)obj);
}
}
public delegate Key IndexFunction(DynamicMessage msg);
public delegate bool FilterFunction(DynamicMessage msg);
private class KVIndexData {
public IndexFunction Handle;
public Dictionary<Key, DynamicMessage> Index;
}
private class KLIndexData {
public IndexFunction Handle;
public Dictionary<Key, List<DynamicMessage>> Index;
public IComparer<DynamicMessage> SortRule;
}
private List<FilterFunction> filters = new List<FilterFunction>();
private List<KVIndexData> kvIndex = new List<KVIndexData>();
private List<KLIndexData> klIndex = new List<KLIndexData>();
public ExcelConfigSet(DynamicFactory fact, string file_name, string protocol_name) {
factory = fact;
fileName = file_name;
protocol = protocol_name;
}
public string FileName {
get { return fileName; }
}
public string Protocol {
get { return protocol; }
}
/// <summary>
/// 清空配置
/// </summary>
public void Clear() {
datas.Clear();
foreach (var index in kvIndex) {
index.Index.Clear();
}
foreach (var index in klIndex) {
index.Index.Clear();
}
}
/// <summary>
/// 重新加载配置
/// </summary>
/// <returns>返回是否加载成功</returns>
public bool Reload() {
Clear();
try {
var header_desc = factory.GetMsgDiscriptor("com.owent.xresloader.pb.xresloader_datablocks");
if (null == header_desc) {
ExcelConfigManager.LastError = string.Format("load configure file {0} failed, com.owent.xresloader.pb.xresloader_datablocks not registered", fileName);
return false;
}
var msg_desc = factory.GetMsgDiscriptor(protocol);
if (null == msg_desc) {
ExcelConfigManager.LastError = string.Format("load configure file {0} failed, {1} not registered", fileName, protocol);
return false;
}
DynamicMessage data_set = factory.Decode(header_desc, ExcelConfigManager.GetFileStream(fileName));
if (null == data_set) {
ExcelConfigManager.LastError = string.Format("load configure file {0} failed, {1}", fileName, factory.LastError);
return false;
}
foreach(var cfg_item in data_set.GetFieldList("data_block")) {
DynamicMessage data_item = factory.Decode(msg_desc, new MemoryStream((byte[])cfg_item));
if (null == data_item) {
ExcelConfigManager.LastError = string.Format("load configure file {0} failed, {1}", fileName, factory.LastError);
continue;
}
bool filter_pass = true;
foreach (var fn in filters) {
filter_pass = fn(data_item);
if (!filter_pass) {
break;
}
}
if (!filter_pass) {
continue;
}
datas.Add(data_item);
foreach (var index in kvIndex) {
if (null != index.Handle) {
Key key = index.Handle(data_item);
index.Index[key] = data_item;
}
}
foreach (var index in klIndex) {
if (null != index.Handle) {
List<DynamicMessage> ls;
Key key = index.Handle(data_item);
if (index.Index.TryGetValue(key, out ls)) {
ls.Add(data_item);
} else {
index.Index[key] = new List<DynamicMessage> { data_item };
}
}
}
}
foreach (var index in klIndex) {
if (null != index.SortRule) {
foreach (var ls in index.Index) {
ls.Value.Sort(index.SortRule);
}
}
}
} catch (Exception e) {
ExcelConfigManager.LastError = string.Format("{0}", e.Message);
return false;
}
return true;
}
/// <summary>
/// 添加Key-Value型索引
/// </summary>
/// <param name="index">索引ID,从0开始,每一组配置都可以添加多个索引。请保持索引ID尽量小</param>
/// <param name="fn">取索引Key的函数</param>
/// <returns>自身</returns>
public ExcelConfigSet AddKVIndex(int index, IndexFunction fn) {
if (index < 0) {
throw new ArgumentException("index must not be negetive");
}
if (null == fn) {
throw new ArgumentNullException("IndexFunction");
}
while (kvIndex.Count <= index) {
KVIndexData obj = new KVIndexData();
obj.Handle = null;
obj.Index = new Dictionary<Key, DynamicMessage>();
kvIndex.Add(obj);
}
KVIndexData index_set = kvIndex[index];
index_set.Handle = fn;
foreach (var data_item in datas) {
index_set.Index[index_set.Handle(data_item)] = data_item;
}
return this;
}
/// <summary>
/// 添加Key-Value型索引,索引ID为0
/// </summary>
/// <param name="fn">取索引Key的函数</param>
/// <returns>自身</returns>
public ExcelConfigSet AddKVIndex(IndexFunction fn) { return AddKVIndex(0, fn); }
/// <summary>
/// 按协议的字段名添加Key-Value型索引,索引ID为0
/// </summary>
/// <param name="key">字段名</param>
/// <returns></returns>
public ExcelConfigSet AddKVIndexAuto(string key) { return AddKVIndex(0, item => new Key(item.GetFieldValue(key))); }
/// <summary>
/// 添加Key-List型索引
/// </summary>
/// <param name="index">索引ID,从0开始,每一组配置都可以添加多个索引。请保持索引ID尽量小</param>
/// <param name="fn">取索引Key的函数</param>
/// <returns>自身</returns>
public ExcelConfigSet AddKLIndex(int index, IndexFunction fn) {
if (index < 0) {
throw new ArgumentException("index must not be negetive");
}
if (null == fn) {
throw new ArgumentNullException("IndexFunction");
}
while (klIndex.Count <= index) {
KLIndexData obj = new KLIndexData();
obj.Handle = null;
obj.Index = new Dictionary<Key, List<DynamicMessage>>();
obj.SortRule = null;
klIndex.Add(obj);
}
KLIndexData index_set = klIndex[index];
index_set.Handle = fn;
foreach (var data_item in datas) {
Key key = index_set.Handle(data_item);
List<DynamicMessage> ls;
if (index_set.Index.TryGetValue(key, out ls)) {
ls.Add(data_item);
} else {
index_set.Index[key] = new List<DynamicMessage>() { data_item };
}
}
return this;
}
/// <summary>
/// 设置Key-List索引的排序规则,索引ID为0
/// </summary>
/// <param name="fn">排序函数</param>
/// <returns>自身</returns>
public ExcelConfigSet SetKLSortRule(IComparer<DynamicMessage> fn) {
return SetKLSortRule(0, fn);
}
/// <summary>
/// 设置Key-List索引的排序规则,索引ID为0
/// </summary>
/// <param name="index">索引ID</param>
/// <param name="fn">排序函数</param>
/// <returns>自身</returns>
public ExcelConfigSet SetKLSortRule(int index, IComparer<DynamicMessage> fn) {
if (index < 0) {
throw new ArgumentException("index must not be negetive");
}
if (index >= klIndex.Count) {
throw new ArgumentException("index extended the ");
}
if (null == fn) {
throw new ArgumentNullException("IndexFunction");
}
klIndex[index].SortRule = fn;
foreach (var index_set in klIndex[index].Index) {
index_set.Value.Sort(fn);
}
return this;
}
/// <summary>
/// 添加过滤器,不符合规则的数据会被忽略
/// </summary>
/// <param name="fn">规则函数,返回false表示要忽略</param>
/// <returns>-1或添加前的过滤器数量</returns>
public int AddFilter(FilterFunction fn) {
if (null == fn) {
return -1;
}
filters.Add(fn);
return filters.Count - 1;
}
/// <summary>
/// 获取Key-Value数据
/// </summary>
/// <param name="type">索引ID</param>
/// <param name="key">Key</param>
/// <returns>动态消息对象,找不到则返回null</returns>
public DynamicMessage GetKV(int type, Key key) {
if (type < 0 || type >= kvIndex.Count) {
return null;
}
DynamicMessage ret;
if (kvIndex[type].Index.TryGetValue(key, out ret)) {
return ret;
}
return null;
}
/// <summary>
/// 获取Key-Value数据
/// </summary>
/// <param name="key">Key</param>
/// <returns>动态消息对象,找不到则返回null</returns>
public DynamicMessage GetKV(Key key) {
return GetKV(0, key);
}
/// <summary>
/// 获取Key-Value数据
/// </summary>
/// <param name="objKey">Key</param>
/// <returns>动态消息对象,找不到则返回null</returns>
public DynamicMessage GetKVAuto(object objKey) {
return GetKV(0, new Key(objKey));
}
/// <summary>
/// 获取Key-List数据
/// </summary>
/// <param name="type">索引ID</param>
/// <param name="key">Key</param>
/// <returns>动态消息对象,找不到则返回null</returns>
public List<DynamicMessage> GetKL(int type, Key key) {
if (type < 0 || type >= klIndex.Count) {
return null;
}
List<DynamicMessage> ret;
if (klIndex[type].Index.TryGetValue(key, out ret)) {
return ret;
}
return null;
}
/// <summary>
/// 获取Key-List数据
/// </summary>
/// <param name="key">Key</param>
/// <returns>动态消息对象,找不到则返回null</returns>
public List<DynamicMessage> GetKL(Key key) {
return GetKL(0, key);
}
}
}