DataNodeManager.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. //------------------------------------------------------------
  2. // Game Framework
  3. // Copyright © 2013-2021 loyalsoft. All rights reserved.
  4. // Homepage: http://www.game7000.com/
  5. // Feedback: http://www.game7000.com/
  6. //------------------------------------------------------------
  7. using System;
  8. namespace GameFramework.DataNode
  9. {
  10. /// <summary>
  11. /// 数据结点管理器。
  12. /// </summary>
  13. internal sealed partial class DataNodeManager : GameFrameworkModule, IDataNodeManager
  14. {
  15. private static readonly string[] EmptyStringArray = new string[] { };
  16. private static readonly string[] PathSplitSeparator = new string[] { ".", "/", "\\" };
  17. private const string RootName = "<Root>";
  18. private DataNode m_Root;
  19. /// <summary>
  20. /// 初始化数据结点管理器的新实例。
  21. /// </summary>
  22. public DataNodeManager()
  23. {
  24. m_Root = DataNode.Create(RootName, null);
  25. }
  26. /// <summary>
  27. /// 获取根数据结点。
  28. /// </summary>
  29. public IDataNode Root
  30. {
  31. get
  32. {
  33. return m_Root;
  34. }
  35. }
  36. /// <summary>
  37. /// 数据结点管理器轮询。
  38. /// </summary>
  39. /// <param name="elapseSeconds">逻辑流逝时间,以秒为单位。</param>
  40. /// <param name="realElapseSeconds">真实流逝时间,以秒为单位。</param>
  41. internal override void Update(float elapseSeconds, float realElapseSeconds)
  42. {
  43. }
  44. /// <summary>
  45. /// 关闭并清理数据结点管理器。
  46. /// </summary>
  47. internal override void Shutdown()
  48. {
  49. ReferencePool.Release(m_Root);
  50. m_Root = null;
  51. }
  52. /// <summary>
  53. /// 根据类型获取数据结点的数据。
  54. /// </summary>
  55. /// <typeparam name="T">要获取的数据类型。</typeparam>
  56. /// <param name="path">相对于 node 的查找路径。</param>
  57. /// <returns>指定类型的数据。</returns>
  58. public T GetData<T>(string path) where T : Variable
  59. {
  60. return GetData<T>(path, null);
  61. }
  62. /// <summary>
  63. /// 获取数据结点的数据。
  64. /// </summary>
  65. /// <param name="path">相对于 node 的查找路径。</param>
  66. /// <returns>数据结点的数据。</returns>
  67. public Variable GetData(string path)
  68. {
  69. return GetData(path, null);
  70. }
  71. /// <summary>
  72. /// 根据类型获取数据结点的数据。
  73. /// </summary>
  74. /// <typeparam name="T">要获取的数据类型。</typeparam>
  75. /// <param name="path">相对于 node 的查找路径。</param>
  76. /// <param name="node">查找起始结点。</param>
  77. /// <returns>指定类型的数据。</returns>
  78. public T GetData<T>(string path, IDataNode node) where T : Variable
  79. {
  80. IDataNode current = GetNode(path, node);
  81. if (current == null)
  82. {
  83. throw new GameFrameworkException(Utility.Text.Format("Data node is not exist, path '{0}', node '{1}'.", path, node != null ? node.FullName : string.Empty));
  84. }
  85. return current.GetData<T>();
  86. }
  87. /// <summary>
  88. /// 获取数据结点的数据。
  89. /// </summary>
  90. /// <param name="path">相对于 node 的查找路径。</param>
  91. /// <param name="node">查找起始结点。</param>
  92. /// <returns>数据结点的数据。</returns>
  93. public Variable GetData(string path, IDataNode node)
  94. {
  95. IDataNode current = GetNode(path, node);
  96. if (current == null)
  97. {
  98. throw new GameFrameworkException(Utility.Text.Format("Data node is not exist, path '{0}', node '{1}'.", path, node != null ? node.FullName : string.Empty));
  99. }
  100. return current.GetData();
  101. }
  102. /// <summary>
  103. /// 设置数据结点的数据。
  104. /// </summary>
  105. /// <typeparam name="T">要设置的数据类型。</typeparam>
  106. /// <param name="path">相对于 node 的查找路径。</param>
  107. /// <param name="data">要设置的数据。</param>
  108. public void SetData<T>(string path, T data) where T : Variable
  109. {
  110. SetData(path, data, null);
  111. }
  112. /// <summary>
  113. /// 设置数据结点的数据。
  114. /// </summary>
  115. /// <param name="path">相对于 node 的查找路径。</param>
  116. /// <param name="data">要设置的数据。</param>
  117. public void SetData(string path, Variable data)
  118. {
  119. SetData(path, data, null);
  120. }
  121. /// <summary>
  122. /// 设置数据结点的数据。
  123. /// </summary>
  124. /// <typeparam name="T">要设置的数据类型。</typeparam>
  125. /// <param name="path">相对于 node 的查找路径。</param>
  126. /// <param name="data">要设置的数据。</param>
  127. /// <param name="node">查找起始结点。</param>
  128. public void SetData<T>(string path, T data, IDataNode node) where T : Variable
  129. {
  130. IDataNode current = GetOrAddNode(path, node);
  131. current.SetData(data);
  132. }
  133. /// <summary>
  134. /// 设置数据结点的数据。
  135. /// </summary>
  136. /// <param name="path">相对于 node 的查找路径。</param>
  137. /// <param name="data">要设置的数据。</param>
  138. /// <param name="node">查找起始结点。</param>
  139. public void SetData(string path, Variable data, IDataNode node)
  140. {
  141. IDataNode current = GetOrAddNode(path, node);
  142. current.SetData(data);
  143. }
  144. /// <summary>
  145. /// 获取数据结点。
  146. /// </summary>
  147. /// <param name="path">相对于 node 的查找路径。</param>
  148. /// <returns>指定位置的数据结点,如果没有找到,则返回空。</returns>
  149. public IDataNode GetNode(string path)
  150. {
  151. return GetNode(path, null);
  152. }
  153. /// <summary>
  154. /// 获取数据结点。
  155. /// </summary>
  156. /// <param name="path">相对于 node 的查找路径。</param>
  157. /// <param name="node">查找起始结点。</param>
  158. /// <returns>指定位置的数据结点,如果没有找到,则返回空。</returns>
  159. public IDataNode GetNode(string path, IDataNode node)
  160. {
  161. IDataNode current = node ?? m_Root;
  162. string[] splitedPath = GetSplitedPath(path);
  163. foreach (string i in splitedPath)
  164. {
  165. current = current.GetChild(i);
  166. if (current == null)
  167. {
  168. return null;
  169. }
  170. }
  171. return current;
  172. }
  173. /// <summary>
  174. /// 获取或增加数据结点。
  175. /// </summary>
  176. /// <param name="path">相对于 node 的查找路径。</param>
  177. /// <returns>指定位置的数据结点,如果没有找到,则创建相应的数据结点。</returns>
  178. public IDataNode GetOrAddNode(string path)
  179. {
  180. return GetOrAddNode(path, null);
  181. }
  182. /// <summary>
  183. /// 获取或增加数据结点。
  184. /// </summary>
  185. /// <param name="path">相对于 node 的查找路径。</param>
  186. /// <param name="node">查找起始结点。</param>
  187. /// <returns>指定位置的数据结点,如果没有找到,则增加相应的数据结点。</returns>
  188. public IDataNode GetOrAddNode(string path, IDataNode node)
  189. {
  190. IDataNode current = node ?? m_Root;
  191. string[] splitedPath = GetSplitedPath(path);
  192. foreach (string i in splitedPath)
  193. {
  194. current = current.GetOrAddChild(i);
  195. }
  196. return current;
  197. }
  198. /// <summary>
  199. /// 移除数据结点。
  200. /// </summary>
  201. /// <param name="path">相对于 node 的查找路径。</param>
  202. public void RemoveNode(string path)
  203. {
  204. RemoveNode(path, null);
  205. }
  206. /// <summary>
  207. /// 移除数据结点。
  208. /// </summary>
  209. /// <param name="path">相对于 node 的查找路径。</param>
  210. /// <param name="node">查找起始结点。</param>
  211. public void RemoveNode(string path, IDataNode node)
  212. {
  213. IDataNode current = node ?? m_Root;
  214. IDataNode parent = current.Parent;
  215. string[] splitedPath = GetSplitedPath(path);
  216. foreach (string i in splitedPath)
  217. {
  218. parent = current;
  219. current = current.GetChild(i);
  220. if (current == null)
  221. {
  222. return;
  223. }
  224. }
  225. if (parent != null)
  226. {
  227. parent.RemoveChild(current.Name);
  228. }
  229. }
  230. /// <summary>
  231. /// 移除所有数据结点。
  232. /// </summary>
  233. public void Clear()
  234. {
  235. m_Root.Clear();
  236. }
  237. /// <summary>
  238. /// 数据结点路径切分工具函数。
  239. /// </summary>
  240. /// <param name="path">要切分的数据结点路径。</param>
  241. /// <returns>切分后的字符串数组。</returns>
  242. private static string[] GetSplitedPath(string path)
  243. {
  244. if (string.IsNullOrEmpty(path))
  245. {
  246. return EmptyStringArray;
  247. }
  248. return path.Split(PathSplitSeparator, StringSplitOptions.RemoveEmptyEntries);
  249. }
  250. }
  251. }