You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
6.4 KiB

  1. unit uengShaderPartCntr;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils,
  7. uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs;
  8. type
  9. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  10. TengShaderPartCntr = class(TengShaderCodePart)
  11. { Code Loading & Storage }
  12. private
  13. fChildren: TengShaderCodePartList;
  14. procedure AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean = false);
  15. function HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
  16. protected { virtual getter }
  17. function GetCount: Integer; override;
  18. function GetChild(const aIndex: Integer): TengShaderPart; override;
  19. function GetText: String; override;
  20. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  21. { Code Generation }
  22. public
  23. procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;
  24. { General }
  25. public
  26. procedure Clear; virtual;
  27. constructor Create(const aParent: TengShaderPart); override;
  28. destructor Destroy; override;
  29. end;
  30. implementation
  31. uses
  32. uengShaderPartKeyValuePair, uengShaderPartClass, uengShaderPartMessage, uengShaderPartMeta,
  33. uengShaderPartCall, uengShaderPartProc, uengShaderPartText, uengShaderPartEcho, uengShaderPartIf,
  34. uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment, uengShaderFileConstants
  35. {$IFDEF DEBUG}
  36. , uengShaderFileTypes
  37. {$ENDIF}
  38. ;
  39. const
  40. TOKEN_CLASSES: array[0..21] of CengShaderCodePart = (
  41. TengShaderPartCall,
  42. TengShaderPartClass,
  43. TengShaderPartConst,
  44. TengShaderPartStatic,
  45. TengShaderPartLineBreak,
  46. TengShaderPartCommandEnd,
  47. TengShaderPartComment,
  48. TengShaderPartEcho,
  49. TengShaderPartError,
  50. TengShaderPartMain,
  51. TengShaderPartIf,
  52. TengShaderPartInclude,
  53. TengShaderPartInherited,
  54. TengShaderPartFunc,
  55. TengShaderPartInfo,
  56. TengShaderPartMeta,
  57. TengShaderPartProc,
  58. TengShaderPartProperty,
  59. TengShaderPartUniform,
  60. TengShaderPartVar,
  61. TengShaderPartVarying,
  62. TengShaderPartWarning
  63. );
  64. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. //TengShaderPartCntr////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  66. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. procedure TengShaderPartCntr.AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean);
  68. begin
  69. if aPrepend
  70. then fChildren.PushFirst(aChild)
  71. else fChildren.PushLast(aChild);
  72. end;
  73. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. function TengShaderPartCntr.HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
  75. var
  76. p: TengShaderCodePart;
  77. c: CengShaderCodePart;
  78. begin
  79. p := nil;
  80. for c in TOKEN_CLASSES do begin
  81. if c.CheckToken(aToken) then begin
  82. c.Validate(aArgs, self);
  83. p := c.Create(self);
  84. AddChild(p);
  85. break;
  86. end;
  87. end;
  88. {$IFDEF DEBUG}
  89. if Assigned(p) then
  90. LogMsg(llDebug, 'ParseText: ' + p.ClassName);
  91. {$ENDIF}
  92. if Assigned(p)
  93. then result := p.ParseText(aArgs)
  94. else result := aToken;
  95. end;
  96. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. function TengShaderPartCntr.GetCount: Integer;
  98. begin
  99. result := fChildren.Count;
  100. end;
  101. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  102. function TengShaderPartCntr.GetChild(const aIndex: Integer): TengShaderPart;
  103. begin
  104. result := fChildren[aIndex];
  105. end;
  106. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  107. function TengShaderPartCntr.GetText: String;
  108. var
  109. p: TengShaderPart;
  110. begin
  111. result := '';
  112. for p in self do
  113. result := result + p.Text;
  114. end;
  115. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116. function TengShaderPartCntr.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  117. var
  118. TextObj: TengShaderPartText;
  119. begin
  120. result := '';
  121. fChildren.Clear;
  122. while not aArgs.EndOfFile and (result = '') do begin
  123. TextObj := TengShaderPartText.Create(self);
  124. try
  125. result := TextObj.ParseText(aArgs);
  126. if not TextObj.IsEmpty
  127. then AddChild(TextObj)
  128. else FreeAndNil(TextObj);
  129. except
  130. FreeAndNil(TextObj);
  131. raise;
  132. end;
  133. if (result <> '') then
  134. result := HandleToken(result, aArgs);
  135. end;
  136. end;
  137. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  138. procedure TengShaderPartCntr.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
  139. var
  140. p: TengShaderCodePart;
  141. s: String;
  142. begin
  143. s := GetTokenName;
  144. if (s = '') then
  145. s := ClassName;
  146. aArgs.AddToken(s);
  147. try
  148. for p in fChildren do
  149. p.GenerateCodeIntern(aArgs);
  150. finally
  151. aArgs.AddToken(TOKEN_END);
  152. end;
  153. end;
  154. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  155. procedure TengShaderPartCntr.Clear;
  156. begin
  157. fChildren.Clear;
  158. end;
  159. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  160. constructor TengShaderPartCntr.Create(const aParent: TengShaderPart);
  161. begin
  162. inherited Create(aParent);
  163. fChildren := TengShaderCodePartList.Create(true);
  164. end;
  165. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  166. destructor TengShaderPartCntr.Destroy;
  167. begin
  168. FreeAndNil(fChildren);
  169. inherited Destroy;
  170. end;
  171. end.