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.

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