Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

202 lignes
8.4 KiB

  1. unit uengShaderPartIf;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils,
  7. uengShaderPart, uengShaderPartCntr, uengShaderFileExpression, uengShaderFileParser;
  8. type
  9. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. TengShaderPartIf = class(TengShaderPart)
  11. { Code Loading & Storage }
  12. private
  13. fExpression: TengExpressionItem;
  14. fIfPart: TengShaderPart;
  15. fElsePart: TengShaderPart;
  16. function HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
  17. protected
  18. function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; virtual;
  19. function GetCount: Integer; override;
  20. function GetChild(const aIndex: Integer): TengShaderPart; override;
  21. function GetText: String; override;
  22. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  23. { General }
  24. public
  25. procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchResults); override;
  26. destructor Destroy; override;
  27. { Class Methods }
  28. public
  29. class function GetTokenName: String; override;
  30. end;
  31. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  32. TengShaderPartElIf = class(TengShaderPartIf)
  33. { Code Loading & Storage }
  34. protected
  35. function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; override;
  36. { Class Methods }
  37. public
  38. class function GetTokenName: String; override;
  39. end;
  40. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. TengShaderPartElse = class(TengShaderPartCntr)
  42. { Code Loading & Storage }
  43. protected
  44. function GetText: String; override;
  45. { Class Methods }
  46. public
  47. class function GetTokenName: String; override;
  48. end;
  49. implementation
  50. uses
  51. uengShaderFileTypes, uengShaderFileConstants, uengShaderFileHelper;
  52. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. //TengShaderPartIf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  54. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  55. function TengShaderPartIf.HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
  56. const
  57. TOKEN_CLASSES: array[0..1] of CengShaderPart = (
  58. TengShaderPartElse,
  59. TengShaderPartElIf
  60. );
  61. var
  62. c: CengShaderPart;
  63. begin
  64. for c in TOKEN_CLASSES do begin
  65. if c.CheckToken(aToken) then begin
  66. c.Validate(aArgs, self);
  67. fElsePart := c.Create(self);
  68. break;
  69. end;
  70. end;
  71. if Assigned(fElsePart) then
  72. result := fElsePart.ParseText(aArgs);
  73. result := HandeEndToken(result, aArgs);
  74. end;
  75. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  76. function TengShaderPartIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String;
  77. begin
  78. result := CheckEndToken(aArgs, self);
  79. end;
  80. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. function TengShaderPartIf.GetCount: Integer;
  82. begin
  83. result := 1;
  84. if Assigned(fElsePart) then
  85. inc(result, 1);
  86. end;
  87. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  88. function TengShaderPartIf.GetChild(const aIndex: Integer): TengShaderPart;
  89. begin
  90. if (aIndex < 0) or (aIndex >= Count) then
  91. raise EengOutOfRange.Create(0, Count-1, aIndex, self);
  92. case aIndex of
  93. 0: result := fIfPart;
  94. 1: result := fElsePart;
  95. end;
  96. end;
  97. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  98. function TengShaderPartIf.GetText: String;
  99. begin
  100. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fExpression.GetText + TOKEN_CHAR_END + fIfPart.Text;
  101. if Assigned(fElsePart) then
  102. result := result + fElsePart.Text;
  103. result := result + TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  104. end;
  105. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  106. function TengShaderPartIf.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  107. begin
  108. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  109. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  110. if (aParams.Count < 2) then
  111. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
  112. fExpression := ParseExpression(self, aParams, 1);
  113. fIfPart := TengShaderPartCntr.Create(self);
  114. result := fIfPart.ParseText(aArgs);
  115. result := HandleToken(result, aArgs);
  116. end;
  117. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  118. procedure TengShaderPartIf.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchResults);
  119. begin
  120. if (sfEvaluateIf in aFlags) then begin
  121. inherited FindIntern(aFlags - [sfSearchChildren], aDepth, aTypes, aList);
  122. if (sfSearchChildren in aFlags) then begin
  123. if fExpression.GetValue then begin
  124. if Assigned(fIfPart) then
  125. fIfPart.FindIntern(aFlags, aDepth, aTypes, aList);
  126. end else begin
  127. if Assigned(fElsePart) then
  128. fElsePart.FindIntern(aFlags, aDepth, aTypes, aList);
  129. end;
  130. end;
  131. end;
  132. end;
  133. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  134. destructor TengShaderPartIf.Destroy;
  135. begin
  136. FreeAndNil(fExpression);
  137. FreeAndNil(fIfPart);
  138. FreeAndNil(fElsePart);
  139. inherited Destroy;
  140. end;
  141. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  142. class function TengShaderPartIf.GetTokenName: String;
  143. begin
  144. result := TOKEN_IF;
  145. end;
  146. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  147. //TengShaderPartElIf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  149. function TengShaderPartElIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String;
  150. begin
  151. result := aToken;
  152. if (result <> TOKEN_END) then
  153. raise EengInvalidToken.Create(ClassName, result, aArgs.Line, aArgs.Col, Filename, self);
  154. end;
  155. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  156. class function TengShaderPartElIf.GetTokenName: String;
  157. begin
  158. result := TOKEN_ELIF;
  159. end;
  160. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  161. //TengShaderPartElse////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  162. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  163. function TengShaderPartElse.GetText: String;
  164. begin
  165. result := TOKEN_CHAR_BEGIN + GetTokenName + TOKEN_CHAR_END + inherited GetText;
  166. end;
  167. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  168. class function TengShaderPartElse.GetTokenName: String;
  169. begin
  170. result := TOKEN_ELSE;
  171. end;
  172. end.