Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

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