mirror of
https://github.com/Alex-Rachel/TEngine.git
synced 2025-08-07 16:45:10 +00:00
更新GameTickWatcher 以及配置表工具
更新GameTickWatcher 以及配置表工具
This commit is contained in:
@@ -5,14 +5,34 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace TEngine
|
namespace TEngine
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 过滤配置
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TType"></typeparam>
|
||||||
|
/// <param name="val"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public delegate bool FilterResBin<TType>(TType val);
|
||||||
|
/// <summary>
|
||||||
|
/// 计算拼接Key
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="KeyType"></typeparam>
|
||||||
|
/// <typeparam name="TType"></typeparam>
|
||||||
|
/// <param name="val"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public delegate KeyType ConvertDictionaryKey<KeyType, TType>(TType val);
|
||||||
|
|
||||||
public class ResConfigUtil
|
public class ResConfigUtil
|
||||||
{
|
{
|
||||||
private static StringBuilder m_strBuilder = new StringBuilder();
|
private static StringBuilder m_strBuilder = new StringBuilder();
|
||||||
private static readonly string m_split = "_";
|
private static readonly string m_split = "_";
|
||||||
|
|
||||||
#region 读取接口
|
#region 读取接口
|
||||||
public static List<T> ReadConfigListRes<T>(string fileName)
|
public static List<T> ReadConfigListRes<T>(string fileName = "")
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
fileName = typeof(T).Name;
|
||||||
|
}
|
||||||
string resPath = string.Format("Config/{0}.json",fileName);
|
string resPath = string.Format("Config/{0}.json",fileName);
|
||||||
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
|
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
|
||||||
if (jsonStr == null)
|
if (jsonStr == null)
|
||||||
@@ -27,8 +47,12 @@ namespace TEngine
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<string, T> ReadConfigRes<T>(string fileName)
|
public static Dictionary<string, T> ReadConfigRes<T>(string fileName = "")
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
fileName = typeof(T).Name;
|
||||||
|
}
|
||||||
string resPath = string.Format("Config/{0}.json", fileName);
|
string resPath = string.Format("Config/{0}.json", fileName);
|
||||||
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
|
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
|
||||||
if (jsonStr == null)
|
if (jsonStr == null)
|
||||||
@@ -43,8 +67,12 @@ namespace TEngine
|
|||||||
return dic;
|
return dic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Dictionary<int, T> ReadConfigResIntKey<T>(string fileName)
|
public static Dictionary<int, T> ReadConfigResIntKey<T>(string fileName = "")
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
fileName = typeof(T).Name;
|
||||||
|
}
|
||||||
string resPath = string.Format("Config/{0}.json", fileName);
|
string resPath = string.Format("Config/{0}.json", fileName);
|
||||||
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
|
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
|
||||||
if (jsonStr == null)
|
if (jsonStr == null)
|
||||||
@@ -59,6 +87,42 @@ namespace TEngine
|
|||||||
return dic;
|
return dic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static List<T> ReadResBinDict<K,T>(Dictionary<K, T> dic,ConvertDictionaryKey<K,T> convKey ,string fileName = "")
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
fileName = typeof(T).Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
string resPath = string.Format("Config/{0}.json", fileName);
|
||||||
|
TextAsset jsonStr = TResources.Load<TextAsset>(resPath);
|
||||||
|
if (jsonStr == null)
|
||||||
|
{
|
||||||
|
TLogger.LogError("读取Json配置数据失败:{0}", fileName);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonData = JsonHelper.Instance.Deserialize<List<T>>(jsonStr.text);
|
||||||
|
|
||||||
|
var etr = jsonData.GetEnumerator();
|
||||||
|
if(dic == null)
|
||||||
|
{
|
||||||
|
dic = new Dictionary<K, T>();
|
||||||
|
}
|
||||||
|
while (etr.MoveNext())
|
||||||
|
{
|
||||||
|
var key = convKey(etr.Current);
|
||||||
|
{
|
||||||
|
if (dic.ContainsKey(key))
|
||||||
|
{
|
||||||
|
TLogger.LogError("Config {0} Load Error, Repeat config {1}",typeof(T).ToString(),key.ToString());
|
||||||
|
}
|
||||||
|
dic.Add(key, etr.Current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonData;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public static UInt64 Make64Key(uint key1, uint key2)
|
public static UInt64 Make64Key(uint key1, uint key2)
|
||||||
|
8
Assets/TEngine/Runtime/Config/ResDataBase.meta
Normal file
8
Assets/TEngine/Runtime/Config/ResDataBase.meta
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ddadc0410f1c53a46b575aee186bc96a
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
94
Assets/TEngine/Runtime/Config/ResDataBase/ResDataBase.cs
Normal file
94
Assets/TEngine/Runtime/Config/ResDataBase/ResDataBase.cs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public interface IResRawListInterface<T>
|
||||||
|
{
|
||||||
|
List<T> RawList { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ResDataBase<T> : IResRawListInterface<T>
|
||||||
|
{
|
||||||
|
private IResRawListInterface<T> m_sourceRawList = null;
|
||||||
|
|
||||||
|
private string m_fileName = null;
|
||||||
|
private List<T> m_rawList = null;
|
||||||
|
private bool m_loaded = false;
|
||||||
|
|
||||||
|
public List<T> RawList
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
CheckLoad();
|
||||||
|
return m_rawList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void InitBase(string fileName)
|
||||||
|
{
|
||||||
|
m_fileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void InitBase(IResRawListInterface<T> sourceList)
|
||||||
|
{
|
||||||
|
m_sourceRawList = sourceList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ClearBase()
|
||||||
|
{
|
||||||
|
m_loaded = false;
|
||||||
|
m_rawList = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void CheckLoad()
|
||||||
|
{
|
||||||
|
if (m_loaded)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
GameTickWatcher tickWatcher = new GameTickWatcher();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_loaded = true;
|
||||||
|
if (m_sourceRawList != null)
|
||||||
|
{
|
||||||
|
m_rawList = LoadFromSourceList(m_sourceRawList);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_rawList = LoadFromFile(m_fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rawList == null)
|
||||||
|
{
|
||||||
|
m_rawList = new List<T>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
TLogger.LogInfo("read config {0} used time: {1}", typeof(T).ToString(), tickWatcher.ElapseTime());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#region 处理载入
|
||||||
|
|
||||||
|
protected virtual List<T> LoadFromFile(string fileName)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual List<T> LoadFromSourceList(IResRawListInterface<T> sourceList)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f66e08f903a6801468e66394daca48d0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
108
Assets/TEngine/Runtime/Config/ResDataBase/ResDictionary.cs
Normal file
108
Assets/TEngine/Runtime/Config/ResDataBase/ResDictionary.cs
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public class ResDictionary<K, T> : ResDataBase<T> where T : new()
|
||||||
|
{
|
||||||
|
private FilterResBin<T> m_filter = null;
|
||||||
|
private ConvertDictionaryKey<K, T> m_convKey = null;
|
||||||
|
private Dictionary<K, T> m_data = null;
|
||||||
|
|
||||||
|
public Dictionary<K, T> Data
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
CheckLoad();
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Init(string fileName, ConvertDictionaryKey<K, T> convKey)
|
||||||
|
{
|
||||||
|
InitBase(fileName);
|
||||||
|
m_convKey = convKey;
|
||||||
|
m_filter = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Init(ConvertDictionaryKey<K, T> convKey)
|
||||||
|
{
|
||||||
|
Init(string.Empty, convKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Init(IResRawListInterface<T> rawList, ConvertDictionaryKey<K, T> convKey, FilterResBin<T> filter = null)
|
||||||
|
{
|
||||||
|
InitBase(rawList);
|
||||||
|
m_convKey = convKey;
|
||||||
|
m_filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
m_data = null;
|
||||||
|
ClearBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override List<T> LoadFromSourceList(IResRawListInterface<T> sourceList)
|
||||||
|
{
|
||||||
|
m_data = new Dictionary<K, T>();
|
||||||
|
var rawList = sourceList.RawList;
|
||||||
|
for (int i = 0; i < rawList.Count; i++)
|
||||||
|
{
|
||||||
|
var config = rawList[i];
|
||||||
|
if (m_filter != null && !m_filter(config))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var key = m_convKey(config);
|
||||||
|
if (m_data.ContainsKey(key))
|
||||||
|
{
|
||||||
|
TLogger.LogError("Config {0} load error, repeat config: {0}", typeof(T).ToString(), key.ToString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_data.Add(key, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawList;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override List<T> LoadFromFile(string fileName)
|
||||||
|
{
|
||||||
|
m_data = new Dictionary<K, T>();
|
||||||
|
|
||||||
|
///读取文件不支持filter,实际也没这个需求
|
||||||
|
TLogger.LogAssert(m_filter == null);
|
||||||
|
|
||||||
|
List<T> rawList;
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
rawList = ResConfigUtil.ReadResBinDict(m_data, m_convKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rawList = ResConfigUtil.ReadResBinDict(m_data, m_convKey,fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetValue(K key, out T itemData, bool showLog = false)
|
||||||
|
{
|
||||||
|
if (Data.TryGetValue(key, out itemData))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showLog)
|
||||||
|
{
|
||||||
|
TLogger.LogError("get config {0} failed, key: {1}!", typeof(T), key);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: efcf1d5d517018a4795f384a746dcb5b
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
85
Assets/TEngine/Runtime/Config/ResDataBase/ResList.cs
Normal file
85
Assets/TEngine/Runtime/Config/ResDataBase/ResList.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
public class ResList<T> : ResDataBase<T> where T : new()
|
||||||
|
{
|
||||||
|
private Comparison<T> m_comparer;
|
||||||
|
|
||||||
|
public List<T> Data
|
||||||
|
{
|
||||||
|
get { return RawList; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化配置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="comparer">如果需要排序,那么传入排序函数</param>
|
||||||
|
public void Init(Comparison<T> comparer = null)
|
||||||
|
{
|
||||||
|
InitBase(string.Empty);
|
||||||
|
m_comparer = comparer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化配置
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">指定配置文件名</param>
|
||||||
|
/// <param name="comparer">如果需要排序,那么传入排序函数</param>
|
||||||
|
public void Init(string fileName, Comparison<T> comparer = null)
|
||||||
|
{
|
||||||
|
InitBase(fileName);
|
||||||
|
m_comparer = comparer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
ClearBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override List<T> LoadFromFile(string fileName)
|
||||||
|
{
|
||||||
|
List<T> listData;
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
{
|
||||||
|
listData = ResConfigUtil.ReadConfigListRes<T>();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
listData = ResConfigUtil.ReadConfigListRes<T>(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
///增加排序功能
|
||||||
|
if (m_comparer != null)
|
||||||
|
{
|
||||||
|
listData.Sort(m_comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return listData;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override List<T> LoadFromSourceList(IResRawListInterface<T> sourceList)
|
||||||
|
{
|
||||||
|
if (m_comparer != null)
|
||||||
|
{
|
||||||
|
List<T> listSorted = new List<T>();
|
||||||
|
|
||||||
|
var list = sourceList.RawList;
|
||||||
|
for (int i = 0; i < list.Count; i++)
|
||||||
|
{
|
||||||
|
listSorted.Add(list[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
listSorted.Sort(m_comparer);
|
||||||
|
|
||||||
|
return listSorted;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sourceList.RawList;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Config/ResDataBase/ResList.cs.meta
Normal file
11
Assets/TEngine/Runtime/Config/ResDataBase/ResList.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e387a6e0873c0724981315547f5d83c1
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
30
Assets/TEngine/Runtime/Core/GameTickWatcher.cs
Normal file
30
Assets/TEngine/Runtime/Core/GameTickWatcher.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
namespace TEngine
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用来在多线程下检测耗时
|
||||||
|
/// </summary>
|
||||||
|
public class GameTickWatcher
|
||||||
|
{
|
||||||
|
private long m_startTick = 0;
|
||||||
|
|
||||||
|
public GameTickWatcher()
|
||||||
|
{
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
m_startTick = System.DateTime.Now.Ticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用时
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public float ElapseTime()
|
||||||
|
{
|
||||||
|
long endTick = System.DateTime.Now.Ticks;
|
||||||
|
return (float)((endTick - m_startTick) / 10000) / 1000.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/TEngine/Runtime/Core/GameTickWatcher.cs.meta
Normal file
11
Assets/TEngine/Runtime/Core/GameTickWatcher.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e6ceaf7f190a870479bfba811f443ab5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
Reference in New Issue
Block a user