Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

246 linhas
8.4 KiB

  1. unit uengShaderPartClass;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils,
  7. uengShaderPart, uengShaderGenerator, uengShaderGeneratorArgs, uengShaderFileParser
  8. {$IFDEF SHADER_FILE_USE_BITSPACE_UTILS}
  9. , uutlGenerics
  10. {$ELSE}
  11. , uengShaderFileGenerics
  12. {$ENDIF}
  13. ;
  14. type
  15. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  16. TengShaderPartClass = class;
  17. TengShaderPartClassList = specialize TutlSimpleList<TengShaderPartClass>;
  18. TengShaderPartClass = class(TengShaderGenerator)
  19. { Code Loading & Storage }
  20. private { member }
  21. fName: String;
  22. fExtends: TStringList;
  23. fInherited: TengShaderPartClassList;
  24. private { getter }
  25. function GetExtends: TStrings;
  26. procedure UpdateInherited;
  27. protected { virtual getter }
  28. function GetText: String; override;
  29. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  30. procedure UpdateProperties; override;
  31. { Code Generation }
  32. public
  33. procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;
  34. { General }
  35. public
  36. property Name: String read fName;
  37. property Extends: TStrings read GetExtends;
  38. property InheritedClasses: TengShaderPartClassList read fInherited;
  39. constructor Create(const aParent: TengShaderPart); override;
  40. destructor Destroy; override;
  41. { Class Methods }
  42. public
  43. class function GetTokenName: String; override;
  44. class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); override;
  45. end;
  46. TengShaderPartClassMap = specialize TutlMap<string, TengShaderPartClass>;
  47. implementation
  48. uses
  49. uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartKeyValuePair,
  50. uengShaderPartScope, uengShaderFile;
  51. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  52. //TengShaderPartClass///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  54. function TengShaderPartClass.GetExtends: TStrings;
  55. begin
  56. result := fExtends;
  57. end;
  58. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  59. procedure TengShaderPartClass.UpdateInherited;
  60. procedure FilterResults(const aName: String; const aResults, aNewResults: TengShaderPartList);
  61. var
  62. p: TengShaderPart;
  63. begin
  64. aNewResults.Clear;
  65. for p in aResults do
  66. if ((p as TengShaderPartClass).Name = aName) then
  67. aNewResults.Add(p);
  68. end;
  69. var
  70. sr, res: TengSearchResults;
  71. walker: TengSearchWalker;
  72. s: String;
  73. begin
  74. if (fExtends.Count <= 0) then
  75. exit;
  76. sr := TengSearchResults.Create;
  77. res := TengSearchResults.Create;
  78. walker := TengSearchWalker.Create(sr);
  79. try
  80. walker.Owner := self;
  81. walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartClass);
  82. walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
  83. walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
  84. walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
  85. walker.SearchFlags := [
  86. sfIgnoreOwner,
  87. sfSearchChildrenLazy,
  88. sfSearchChildren,
  89. sfSearchParents
  90. ];
  91. fInherited.Clear;
  92. walker.Run(self);
  93. for s in fExtends do begin
  94. FilterResults(s, sr, res);
  95. fInherited.Add(ExtractSearchResult(self, s, res) as TengShaderPartClass);
  96. end;
  97. finally
  98. FreeAndNil(walker);
  99. FreeAndNil(res);
  100. FreeAndNil(sr);
  101. end;
  102. end;
  103. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. function TengShaderPartClass.GetText: String;
  105. var
  106. s: String;
  107. begin
  108. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fName;
  109. if (fExtends.Count > 0) then begin
  110. result := result + ' ' + TOKEN_EXTENDS;
  111. for s in fExtends do
  112. result := result + ' ' + s;
  113. end;
  114. result := result + TOKEN_CHAR_END +
  115. inherited GetText +
  116. TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  117. end;
  118. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. function TengShaderPartClass.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  120. var
  121. i: Integer;
  122. begin
  123. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  124. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  125. if (aParams.Count < 2) then
  126. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
  127. with aParams[1] do begin
  128. if not IsValidIdentifier(Name) then
  129. raise EengInvalidIdentifier.Create(Name, self);
  130. fName := Name;
  131. end;
  132. if (aParams.Count > 2) then begin
  133. if (aParams.Count < 4) then
  134. raise EengInvalidParamterCount.Create(GetTokenName, 4, -1, self);
  135. if (aParams[2].Name <> TOKEN_EXTENDS) then with aParams[2] do
  136. raise EengInvalidParamter.Create(aParams[2].Name, TOKEN_EXTENDS, Line, Col, Filename, self);
  137. fExtends.Clear;
  138. for i := 3 to aParams.Count-1 do
  139. fExtends.Add(aParams[i].Name);
  140. end;
  141. UpdateInherited;
  142. result := inherited ParseIntern(aArgs, aParams);
  143. result := CheckEndToken(result, aArgs, self);
  144. end;
  145. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  146. procedure TengShaderPartClass.UpdateProperties;
  147. var
  148. sr: TengSearchResults;
  149. walker: TengSearchWalker;
  150. p: TengShaderPart;
  151. c: TengShaderPartClass;
  152. begin
  153. inherited UpdateProperties;
  154. for c in fInherited do
  155. c.CopyProperties(self);
  156. sr := TengSearchResults.Create;
  157. walker := TengSearchWalker.Create(sr);
  158. try
  159. walker.SearchFlags := [sfSearchChildren];
  160. walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty);
  161. walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartClass);
  162. walker.Run(self);
  163. for p in sr.GetReverseEnumerator do
  164. AddProperty(p as TengShaderPartProperty);
  165. finally
  166. FreeAndNil(walker);
  167. FreeAndNil(sr);
  168. end;
  169. end;
  170. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  171. procedure TengShaderPartClass.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
  172. var
  173. c: TengShaderPartClass;
  174. begin
  175. for c in fInherited do
  176. c.GenerateCodeIntern(aArgs);
  177. aArgs.BeginBlock;
  178. try
  179. inherited GenerateCodeIntern(aArgs);
  180. finally
  181. aArgs.EndBlock;
  182. end;
  183. end;
  184. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  185. constructor TengShaderPartClass.Create(const aParent: TengShaderPart);
  186. begin
  187. inherited Create(aParent);
  188. fExtends := TStringList.Create;
  189. fInherited := TengShaderPartClassList.Create(false);
  190. end;
  191. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  192. destructor TengShaderPartClass.Destroy;
  193. begin
  194. FreeAndNil(fInherited);
  195. FreeAndNil(fExtends);
  196. inherited Destroy;
  197. end;
  198. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  199. class function TengShaderPartClass.GetTokenName: String;
  200. begin
  201. result := TOKEN_CLASS;
  202. end;
  203. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  204. class procedure TengShaderPartClass.Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart);
  205. procedure RaiseEx(const aToken: String);
  206. begin
  207. with aArgs do
  208. raise EengShaderPart.Create('token ' + GetTokenName + ' is not allowed in ' + aToken, Line, Col, Filename, aParent);
  209. end;
  210. begin
  211. inherited Validate(aArgs, aParent);
  212. if aParent.HasParent(TengShaderPartClass, true) then
  213. RaiseEx(TengShaderPartClass.GetTokenName);
  214. end;
  215. end.