using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; using System.Collections.Generic; using Newtonsoft; namespace F6 { public delegate bool TraverseCb(T ele); public interface IMetaTable { bool IsNoLoad() { return false; } void Load() { } void PreInit1() { } void ElementsInit(int round) { } void PostInit1() { } } public sealed class MetaTableFieldAttribute : Attribute { public string fieldName; } public class BaseMeta { public Dictionary nameIdxHash = new Dictionary(); } public class BaseTable { public BaseMeta _meta; public BitArray _flags = new BitArray(100); public string _primKeyVal; virtual public bool HasValue(string fieldName) { return this.HasValue(this.GetFieldIdx(fieldName)); } virtual public bool HasValue(int fieldIdx) { return this._flags.Get(fieldIdx); } virtual public int GetFieldIdx(string fieldName) { int idx = 0; this._meta.nameIdxHash.TryGetValue(fieldName, out idx); return idx; } } public class RawMetaTable : IMetaTable where T : BaseTable, new() { protected string fileName; protected string primKey; protected bool noLoad; protected List rawList = new List(); public RawMetaTable(string fileName, string primKey) { this.fileName = fileName; this.primKey = primKey; } public void Traverse(TraverseCb cb) { foreach(var item in this.rawList) { if (!cb(item)) { break; } } } public T RandElement() { if (this.rawList.Count > 0) { return this.rawList[new Random().Next(0, this.rawList.Count)]; } return default(T); } public virtual void Load() { try { BaseMeta baseMeta = new BaseMeta(); { Type tType = typeof(T); Type tBaseType = tType.BaseType; int fieldIdx = 0; foreach(var f in tBaseType.GetFields()) { string fieldName = f.Name; var tAttrs = f.GetCustomAttributes(typeof(MetaTableFieldAttribute), false); if (tAttrs.Length > 0) { var tAttr = (MetaTableFieldAttribute)tAttrs.First(); if (tAttr != null) { fieldName = tAttr.fieldName; } } baseMeta.nameIdxHash.Add(f.Name, fieldIdx); if (!baseMeta.nameIdxHash.ContainsKey(fieldName)) { baseMeta.nameIdxHash.Add(fieldName, fieldIdx); } ++fieldIdx; } } string fileContent = File.ReadAllText(this.fileName); var dataSet = Newtonsoft.Json.JsonConvert.DeserializeObject>>(fileContent); foreach(var row in dataSet) { T t = new T(); t._meta = baseMeta; row.TryGetValue(this.primKey, out t._primKeyVal); Type tType = typeof(T); Type tBaseType = tType.BaseType; int fieldIdx = 0; foreach(var f in tBaseType.GetFields()) { string fieldName = f.Name; var tAttrs = f.GetCustomAttributes(typeof(MetaTableFieldAttribute), false); if (tAttrs.Length > 0) { var tAttr = (MetaTableFieldAttribute)tAttrs.First(); if (tAttr != null) { fieldName = tAttr.fieldName; } } var typeName = f.FieldType.ToString(); string val; if (row.TryGetValue(fieldName, out val)) { switch (typeName) { case "System.Int32": { f.SetValue(t, int.Parse(val)); t._flags.Set(fieldIdx, true); } break; case "System.Int64": { f.SetValue(t, long.Parse(val)); t._flags.Set(fieldIdx, true); } break; case "System.Single": { f.SetValue(t, float.Parse(val)); t._flags.Set(fieldIdx, true); } break; case "System.Double": { f.SetValue(t, double.Parse(val)); t._flags.Set(fieldIdx, true); } break; case "System.String": { f.SetValue(t, val); t._flags.Set(fieldIdx, true); } break; } }//endif ++fieldIdx; } this.rawList.Add(t); } this.LoadPost(); }catch(Exception e) { int i = 0; } } protected virtual void LoadPost() { } } public class IdMetaTable: RawMetaTable where T : BaseTable, new() { protected Dictionary idHash = new Dictionary (); public T GetById(Int64 id) { T v = default(T); this.idHash.TryGetValue(id, out v); return v; } protected override void LoadPost() { base.LoadPost(); long idx = 0; this.Traverse((T ele)=> { if (this.primKey.Equals("")) { this.idHash.Add(idx, ele); } else { this.idHash.Add(long.Parse(ele._primKeyVal), ele); } ++idx; return true; }); } public IdMetaTable(string fileName, string primKey) :base(fileName, primKey) { } } public class NameMetaTable: RawMetaTable where T : BaseTable, new() { protected Dictionary nameHash = new Dictionary(); public T GetByName(string key) { T v = default(T); this.nameHash.TryGetValue(key, out v); return v; } protected override void LoadPost() { base.LoadPost(); this.Traverse((T ele) => { this.nameHash.Add(ele._primKeyVal, ele); return true; }); } public NameMetaTable(string fileName, string primKey):base(fileName, primKey) { } } }