Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

203 Zeilen
6.9 KiB

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