Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

316 řádky
12 KiB

  1. unit uengShaderPart;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils,
  7. uengShaderFileParser, uengShaderFileTypes
  8. {$IFDEF USE_BITSPACE_UTILS}
  9. , uutlGenerics;
  10. {$ELSE}
  11. , fgl;
  12. {$ENDIF}
  13. type
  14. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  15. TengShaderFileSearchFlag = (
  16. sfFirstOnly, // search first match only
  17. sfEvaluateIf, // evaluate if statements before search and process with suitable subtree
  18. sfSearchChildren, // search in children
  19. sfSearchParents, // search in parents
  20. sfCurrentFileOnly // do not search in other files
  21. );
  22. TengShaderFileSearchFlags = set of TengShaderFileSearchFlag;
  23. TengShaderPart = class;
  24. CengShaderPart = class of TengShaderPart;
  25. TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;
  26. TengShaderPart = class(TIntfObjNoRefCount)
  27. { Nested Types }
  28. public type
  29. TEnumerator = class(TObject)
  30. private
  31. fOwner: TengShaderPart;
  32. fPosition: Integer;
  33. function GetCurrent: TengShaderPart;
  34. public
  35. property Current: TengShaderPart read GetCurrent;
  36. function MoveNext: Boolean;
  37. constructor Create(const aOwner: TengShaderPart);
  38. end;
  39. TSearchList = class(TengShaderPartList)
  40. public
  41. constructor Create;
  42. end;
  43. { Code Loading & Storage }
  44. private { members }
  45. fRoot: TengShaderPart;
  46. fParent: TengShaderPart;
  47. fLine: Integer;
  48. fCol: Integer;
  49. protected { virtual getter }
  50. function GetCount: Integer; virtual;
  51. function GetChild(const aIndex: Integer): TengShaderPart; virtual;
  52. function GetText: String; virtual;
  53. function GetFilename: String; virtual;
  54. function GetFileReader: IengShaderFileReader; virtual;
  55. function GetFileWriter: IengShaderFileWriter; virtual;
  56. protected { parse methodes }
  57. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; virtual;
  58. public
  59. function ParseText(const aArgs: TengParseArgs): String;
  60. { General }
  61. protected
  62. procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); virtual;
  63. public { general methods }
  64. property Root: TengShaderPart read fRoot;
  65. property Parent: TengShaderPart read fParent;
  66. property Line: Integer read fLine;
  67. property Col: Integer read fCol;
  68. property Filename: String read GetFilename;
  69. property Text: String read GetText;
  70. property Count: Integer read GetCount;
  71. property FileReader: IengShaderFileReader read GetFileReader;
  72. property FileWriter: IengShaderFileWriter read GetFileWriter;
  73. property Children[const aIndex: Integer]: TengShaderPart read GetChild; default;
  74. function HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean = false): Boolean;
  75. function GetParent(const aType: CengShaderPart; out aPart): Boolean;
  76. function FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
  77. procedure FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
  78. function GetEnumerator: TEnumerator;
  79. constructor Create(const aParent: TengShaderPart); virtual;
  80. { Class Methods }
  81. public
  82. class function GetTokenName: String; virtual;
  83. class function CheckToken(const aToken: String): Boolean; virtual;
  84. class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual;
  85. end;
  86. implementation
  87. uses
  88. uengShaderFileConstants;
  89. function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean;
  90. var
  91. c: CengShaderPart;
  92. begin
  93. result := true;
  94. if (Length(aTypes) = 0) then
  95. exit;
  96. for c in aTypes do
  97. if (aShaderPart is c) then
  98. exit;
  99. result := false;
  100. end;
  101. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  102. //TengShaderPart.TEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  103. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. function TengShaderPart.TEnumerator.GetCurrent: TengShaderPart;
  105. begin
  106. result := fOwner[fPosition];
  107. end;
  108. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  109. function TengShaderPart.TEnumerator.MoveNext: Boolean;
  110. begin
  111. inc(fPosition);
  112. result := (fPosition < fOwner.Count);
  113. end;
  114. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  115. constructor TengShaderPart.TEnumerator.Create(const aOwner: TengShaderPart);
  116. begin
  117. inherited Create;
  118. fOwner := aOwner;
  119. fPosition := -1;
  120. end;
  121. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  122. //TengShaderPart.TSearchList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  123. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  124. constructor TengShaderPart.TSearchList.Create;
  125. begin
  126. inherited Create(false);
  127. end;
  128. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  129. //TengShaderPart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  130. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. function TengShaderPart.GetCount: Integer;
  132. begin
  133. result := 0;
  134. end;
  135. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  136. function TengShaderPart.{%H-}GetChild(const aIndex: Integer): TengShaderPart;
  137. begin
  138. EengShaderPartInternal.Create('this part does not have any children');
  139. end;
  140. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  141. function TengShaderPart.GetText: String;
  142. begin
  143. result := ''; //DUMMY
  144. end;
  145. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146. function TengShaderPart.GetFilename: String;
  147. begin
  148. if Assigned(fParent)
  149. then result := fParent.Filename
  150. else result := UNKNOWN_FILENAME;
  151. end;
  152. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  153. function TengShaderPart.GetFileReader: IengShaderFileReader;
  154. begin
  155. if Assigned(fParent)
  156. then result := fParent.GetFileReader
  157. else result := nil;
  158. end;
  159. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  160. function TengShaderPart.GetFileWriter: IengShaderFileWriter;
  161. begin
  162. if Assigned(fParent)
  163. then result := fParent.GetFileWriter
  164. else result := nil;
  165. end;
  166. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  167. function TengShaderPart.ParseText(const aArgs: TengParseArgs): String;
  168. var
  169. params: TengTokenParameterList;
  170. begin
  171. params := TengTokenParameterList.Create(Filename);
  172. try
  173. fCol := aArgs.Col;
  174. fLine := aArgs.Line;
  175. if (GetTokenName <> '') then
  176. aArgs.ExtractToken(params);
  177. result := ParseIntern(aArgs, params);
  178. finally
  179. FreeAndNil(params);
  180. end;
  181. end;
  182. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  183. procedure TengShaderPart.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
  184. var
  185. c: TengShaderPart;
  186. begin
  187. if (sfFirstOnly in aFlags) and (aList.Count > 0) then
  188. exit;
  189. if CheckType(self, aTypes) then
  190. aList.Add(self);
  191. if (sfSearchChildren in aFlags) then begin
  192. for c in self do
  193. c.FindIntern(aFlags, aDepth+1, aTypes, aList);
  194. end;
  195. if (sfSearchParents in aFlags) and Assigned(Parent) then
  196. Parent.FindIntern(aFlags, aDepth-1, aTypes, aList);
  197. end;
  198. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  199. function TengShaderPart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  200. begin
  201. result := ''; // DUMMY
  202. end;
  203. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  204. function TengShaderPart.HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean): Boolean;
  205. var
  206. p: TengShaderPart;
  207. begin
  208. result := (aIncludeSelf and (self is aType)) or GetParent(aType, p);
  209. end;
  210. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  211. function TengShaderPart.GetParent(const aType: CengShaderPart; out aPart): Boolean;
  212. begin
  213. result := true;
  214. if (fParent is aType) then
  215. TengShaderPart(aPart) := fParent
  216. else if Assigned(fParent) then
  217. result := fParent.GetParent(aType, aPart)
  218. else
  219. result := false;
  220. end;
  221. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  222. function TengShaderPart.FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
  223. var
  224. l: TSearchList;
  225. begin
  226. l := TSearchList.Create;
  227. try
  228. FindIntern(aFlags + [sfFirstOnly], 0, aTypes, l);
  229. if (l.Count > 0)
  230. then result := l[0]
  231. else result := nil;
  232. finally
  233. FreeAndNil(l);
  234. end;
  235. end;
  236. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  237. procedure TengShaderPart.FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
  238. begin
  239. FindIntern(aFlags, 0, aTypes, aList);
  240. end;
  241. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  242. function TengShaderPart.GetEnumerator: TEnumerator;
  243. begin
  244. result := TEnumerator.Create(self);
  245. end;
  246. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  247. constructor TengShaderPart.Create(const aParent: TengShaderPart);
  248. begin
  249. inherited Create;
  250. fParent := aParent;
  251. if Assigned(fParent)
  252. then fRoot := fParent.Root
  253. else fRoot := nil;
  254. end;
  255. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  256. class function TengShaderPart.GetTokenName: String;
  257. begin
  258. result := ''; // DUMMY
  259. end;
  260. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  261. class function TengShaderPart.CheckToken(const aToken: String): Boolean;
  262. begin
  263. result := (aToken = GetTokenName);
  264. end;
  265. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  266. class procedure TengShaderPart.Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart);
  267. begin
  268. // DUMMY
  269. end;
  270. end.