LabelDictionary.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. using System.Collections.Generic;
  2. namespace NTERA.EmuEra.Game.EraEmu.GameProc
  3. {
  4. //1.713 LogicalLine.csから分割
  5. /// <summary>
  6. /// ラベルのジャンプ先の辞書。Erbファイル読み込み時に作成
  7. /// </summary>
  8. internal sealed class LabelDictionary
  9. {
  10. public LabelDictionary()
  11. {
  12. Initialized = false;
  13. }
  14. /// <summary>
  15. /// 本体。全てのFunctionLabelLineを記録
  16. /// </summary>
  17. Dictionary<string, List<FunctionLabelLine>> labelAtDic = new Dictionary<string, List<FunctionLabelLine>>();
  18. List<FunctionLabelLine> invalidList = new List<FunctionLabelLine>();
  19. List<GotoLabelLine> labelDollarList = new List<GotoLabelLine>();
  20. int count;
  21. Dictionary<string, int> loadedFileDic = new Dictionary<string, int>();
  22. int currentFileCount;
  23. int totalFileCount;
  24. public int Count => count;
  25. /// <summary>
  26. /// これがfalseである間は式中関数は呼べない
  27. /// (つまり関数宣言の初期値として式中関数は使えない)
  28. /// </summary>
  29. public bool Initialized { get; set; }
  30. #region Initialized 前用
  31. public FunctionLabelLine GetSameNameLabel(FunctionLabelLine point)
  32. {
  33. string id = point.LabelName;
  34. if (!labelAtDic.ContainsKey(id))
  35. return null;
  36. if (point.IsError)
  37. return null;
  38. List<FunctionLabelLine> labelList = labelAtDic[id];
  39. if (labelList.Count <= 1)
  40. return null;
  41. return labelList[0];
  42. }
  43. Dictionary<string, List<FunctionLabelLine>[]> eventLabelDic = new Dictionary<string, List<FunctionLabelLine>[]>();
  44. Dictionary<string, FunctionLabelLine> noneventLabelDic = new Dictionary<string, FunctionLabelLine>();
  45. public void SortLabels()
  46. {
  47. foreach (KeyValuePair<string, List<FunctionLabelLine>[]> pair in eventLabelDic)
  48. foreach (List<FunctionLabelLine> list in pair.Value)
  49. list.Clear();
  50. eventLabelDic.Clear();
  51. noneventLabelDic.Clear();
  52. foreach (KeyValuePair<string, List<FunctionLabelLine>> pair in labelAtDic)
  53. {
  54. string key = pair.Key;
  55. List<FunctionLabelLine> list = pair.Value;
  56. if(list.Count > 1)
  57. list.Sort();
  58. if (!list[0].IsEvent)
  59. {
  60. noneventLabelDic.Add(key, list[0]);
  61. GlobalStatic.IdentifierDictionary.resizeLocalVars("ARG", list[0].LabelName, list[0].ArgLength);
  62. GlobalStatic.IdentifierDictionary.resizeLocalVars("ARGS", list[0].LabelName, list[0].ArgsLength);
  63. continue;
  64. }
  65. //1810alpha010 オプションによりイベント関数をイベント関数でないかのように呼び出すことを許可
  66. //eramaker仕様 - #PRI #LATER #SINGLE等を無視し、最先に定義された関数1つのみを呼び出す
  67. if (Config.Config.CompatiCallEvent)
  68. noneventLabelDic.Add(key, list[0]);
  69. List<FunctionLabelLine>[] eventLabels = new List<FunctionLabelLine>[4];
  70. List<FunctionLabelLine> onlylist = new List<FunctionLabelLine>();
  71. List<FunctionLabelLine> prilist = new List<FunctionLabelLine>();
  72. List<FunctionLabelLine> normallist = new List<FunctionLabelLine>();
  73. List<FunctionLabelLine> laterlist = new List<FunctionLabelLine>();
  74. int localMax = 0;
  75. int localsMax = 0;
  76. for (int i = 0; i < list.Count; i++)
  77. {
  78. if (list[i].LocalLength > localMax)
  79. localMax = list[i].LocalLength;
  80. if (list[i].LocalsLength > localsMax)
  81. localsMax = list[i].LocalsLength;
  82. if (list[i].IsOnly)
  83. onlylist.Add(list[i]);
  84. if (list[i].IsPri)
  85. prilist.Add(list[i]);
  86. if (list[i].IsLater)
  87. laterlist.Add(list[i]);//#PRIかつ#LATERなら二重に登録する。eramakerの仕様
  88. if ((!list[i].IsPri) && (!list[i].IsLater))
  89. normallist.Add(list[i]);
  90. }
  91. if (localMax < GlobalStatic.IdentifierDictionary.getLocalDefaultSize("LOCAL"))
  92. localMax = GlobalStatic.IdentifierDictionary.getLocalDefaultSize("LOCAL");
  93. if (localsMax < GlobalStatic.IdentifierDictionary.getLocalDefaultSize("LOCALS"))
  94. localsMax = GlobalStatic.IdentifierDictionary.getLocalDefaultSize("LOCALS");
  95. eventLabels[0] = onlylist;
  96. eventLabels[1] = prilist;
  97. eventLabels[2] = normallist;
  98. eventLabels[3] = laterlist;
  99. for (int i = 0; i < 4; i++)
  100. {
  101. for (int j = 0; j < eventLabels[i].Count; j++)
  102. {
  103. eventLabels[i][j].LocalLength = localMax;
  104. eventLabels[i][j].LocalsLength = localsMax;
  105. }
  106. }
  107. eventLabelDic.Add(key, eventLabels);
  108. }
  109. }
  110. public void RemoveAll()
  111. {
  112. Initialized = false;
  113. count = 0;
  114. foreach (KeyValuePair<string, List<FunctionLabelLine>[]> pair in eventLabelDic)
  115. foreach (List<FunctionLabelLine> list in pair.Value)
  116. list.Clear();
  117. eventLabelDic.Clear();
  118. noneventLabelDic.Clear();
  119. foreach (KeyValuePair<string, List<FunctionLabelLine>> pair in labelAtDic)
  120. pair.Value.Clear();
  121. labelAtDic.Clear();
  122. labelDollarList.Clear();
  123. loadedFileDic.Clear();
  124. invalidList.Clear();
  125. currentFileCount = 0;
  126. totalFileCount = 0;
  127. }
  128. public void RemoveLabelWithPath(string fname)
  129. {
  130. List<FunctionLabelLine> labelLines;
  131. List<FunctionLabelLine> removeLine = new List<FunctionLabelLine>();
  132. List<string> removeKey = new List<string>();
  133. foreach (KeyValuePair<string, List<FunctionLabelLine>> pair in labelAtDic)
  134. {
  135. string key = pair.Key;
  136. labelLines = pair.Value;
  137. foreach (FunctionLabelLine labelLine in labelLines)
  138. {
  139. if (string.Equals(labelLine.Position.Filename, fname, Config.Config.SCIgnoreCase))
  140. removeLine.Add(labelLine);
  141. }
  142. foreach (FunctionLabelLine remove in removeLine)
  143. {
  144. labelLines.Remove(remove);
  145. if (labelLines.Count == 0)
  146. removeKey.Add(key);
  147. }
  148. removeLine.Clear();
  149. }
  150. foreach (string rKey in removeKey)
  151. {
  152. labelAtDic.Remove(rKey);
  153. }
  154. for (int i = 0; i < invalidList.Count; i++)
  155. {
  156. if (string.Equals(invalidList[i].Position.Filename, fname, Config.Config.SCIgnoreCase))
  157. {
  158. invalidList.RemoveAt(i);
  159. i--;
  160. }
  161. }
  162. }
  163. public void AddFilename(string filename)
  164. {
  165. int curCount = 0;
  166. if (loadedFileDic.TryGetValue(filename, out curCount))
  167. {
  168. currentFileCount = curCount;
  169. RemoveLabelWithPath(filename);
  170. return;
  171. }
  172. totalFileCount++;
  173. currentFileCount = totalFileCount;
  174. loadedFileDic.Add(filename, totalFileCount);
  175. }
  176. public void AddLabel(FunctionLabelLine point)
  177. {
  178. point.Index = count;
  179. point.FileIndex = currentFileCount;
  180. count++;
  181. string id = point.LabelName;
  182. if (labelAtDic.ContainsKey(id))
  183. {
  184. labelAtDic[id].Add(point);
  185. }
  186. else
  187. {
  188. List<FunctionLabelLine> labelList = new List<FunctionLabelLine>();
  189. labelList.Add(point);
  190. labelAtDic.Add(id, labelList);
  191. }
  192. }
  193. public bool AddLabelDollar(GotoLabelLine point)
  194. {
  195. string id = point.LabelName;
  196. foreach (GotoLabelLine label in labelDollarList)
  197. {
  198. if (label.LabelName == id && label.ParentLabelLine == point.ParentLabelLine)
  199. return false;
  200. }
  201. labelDollarList.Add(point);
  202. return true;
  203. }
  204. #endregion
  205. public List<FunctionLabelLine>[] GetEventLabels(string key)
  206. {
  207. List<FunctionLabelLine>[] ret = null;
  208. eventLabelDic.TryGetValue(key, out ret);
  209. return ret;
  210. }
  211. public FunctionLabelLine GetNonEventLabel(string key)
  212. {
  213. FunctionLabelLine ret = null;
  214. noneventLabelDic.TryGetValue(key, out ret);
  215. return ret;
  216. }
  217. public List<FunctionLabelLine> GetAllLabels(bool getInvalidList)
  218. {
  219. List<FunctionLabelLine> ret = new List<FunctionLabelLine>();
  220. foreach (List<FunctionLabelLine> list in labelAtDic.Values)
  221. ret.AddRange(list);
  222. if(getInvalidList)
  223. ret.AddRange(invalidList);
  224. return ret;
  225. }
  226. public GotoLabelLine GetLabelDollar(string key, FunctionLabelLine labelAtLine)
  227. {
  228. foreach (GotoLabelLine label in labelDollarList)
  229. {
  230. if ((label.LabelName == key) && (label.ParentLabelLine == labelAtLine))
  231. return label;
  232. }
  233. return null;
  234. }
  235. internal void AddInvalidLabel(FunctionLabelLine invalidLabelLine)
  236. {
  237. invalidList.Add(invalidLabelLine);
  238. }
  239. }
  240. }