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.

175 line
6.3 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(TengShaderCodeGenerator)
  15. { Code Loading & Storage }
  16. private { member }
  17. fName: String;
  18. fExtends: TStringList;
  19. private { getter }
  20. function GetExtends: TStrings;
  21. protected { virtual getter }
  22. function GetText: String; override;
  23. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  24. { General }
  25. protected
  26. procedure UpdateInherited; override;
  27. public
  28. property Name: String read fName;
  29. property Extends: TStrings read GetExtends;
  30. constructor Create(const aParent: TengShaderPart); override;
  31. destructor Destroy; override;
  32. { Class Methods }
  33. public
  34. class function GetTokenName: String; override;
  35. class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); override;
  36. end;
  37. TengShaderPartClassMap = specialize TutlMap<string, TengShaderPartClass>;
  38. implementation
  39. uses
  40. uengShaderFile, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartIf;
  41. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  42. //TengShaderPartClass///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  43. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  44. function TengShaderPartClass.GetExtends: TStrings;
  45. begin
  46. result := fExtends;
  47. end;
  48. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  49. function TengShaderPartClass.GetText: String;
  50. var
  51. s: String;
  52. begin
  53. result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fName;
  54. if (fExtends.Count > 0) then begin
  55. result := result + ' ' + TOKEN_EXTENDS;
  56. for s in fExtends do
  57. result := result + ' ' + s;
  58. end;
  59. result := result + TOKEN_CHAR_END +
  60. inherited GetText +
  61. TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END;
  62. end;
  63. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. function TengShaderPartClass.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  65. var
  66. i: Integer;
  67. begin
  68. if (aParams[0].Name <> GetTokenName) then with aParams[0] do
  69. raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
  70. if (aParams.Count < 2) then
  71. raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, self);
  72. with aParams[1] do begin
  73. if not IsValidIdentifier(Name) then
  74. raise EengInvalidIdentifier.Create(Name, self);
  75. fName := Name;
  76. end;
  77. if (aParams.Count > 2) then begin
  78. if (aParams.Count < 4) then
  79. raise EengInvalidParamterCount.Create(GetTokenName, 4, -1, self);
  80. if (aParams[2].Name <> TOKEN_EXTENDS) then with aParams[2] do
  81. raise EengInvalidParamter.Create(aParams[2].Name, TOKEN_EXTENDS, Line, Col, Filename, self);
  82. fExtends.Clear;
  83. for i := 3 to aParams.Count-1 do
  84. fExtends.Add(aParams[i].Name);
  85. end;
  86. result := inherited ParseIntern(aArgs, aParams);
  87. result := CheckEndToken(aArgs, self);
  88. end;
  89. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. procedure TengShaderPartClass.UpdateInherited;
  91. var
  92. sr: TengShaderPart.TSearchResults;
  93. i: Integer;
  94. s: String;
  95. begin
  96. inherited UpdateInherited;
  97. fInherited.Clear;
  98. sr := TengShaderPart.TSearchResults.Create([TengShaderPartClass]);
  99. try
  100. sr.Ignore := self;
  101. Find([sfSearchChildrenLazy, sfSearchParents, sfParentsFileOnly, sfSearchPrevOnly], sr);
  102. for s in fExtends do begin
  103. i := 0;
  104. while (i >= 0) and (i < sr.Count) do begin
  105. if ((sr[i] as TengShaderPartClass).Name = s) then begin
  106. fInherited.Add(sr[i]);
  107. i := -1;
  108. end;
  109. inc(i);
  110. end;
  111. if (i > 0) or (sr.Count = 0) then
  112. raise EengUnknownIdentifier.Create(s, self);
  113. end;
  114. finally
  115. FreeAndNil(sr);
  116. end;
  117. end;
  118. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  119. constructor TengShaderPartClass.Create(const aParent: TengShaderPart);
  120. begin
  121. inherited Create(aParent);
  122. fExtends := TStringList.Create;
  123. end;
  124. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  125. destructor TengShaderPartClass.Destroy;
  126. begin
  127. FreeAndNil(fExtends);
  128. inherited Destroy;
  129. end;
  130. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  131. class function TengShaderPartClass.GetTokenName: String;
  132. begin
  133. result := TOKEN_CLASS;
  134. end;
  135. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  136. class procedure TengShaderPartClass.Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart);
  137. procedure RaiseEx(const aToken: String);
  138. begin
  139. with aArgs do
  140. raise EengShaderPart.Create('token ' + GetTokenName + ' is not allowed in ' + aToken, Line, Col, Filename, aParent);
  141. end;
  142. begin
  143. inherited Validate(aArgs, aParent);
  144. if aParent.HasParent(TengShaderPartElIf, true) then
  145. RaiseEx(TengShaderPartElIf.GetTokenName);
  146. if aParent.HasParent(TengShaderPartElse, true) then
  147. RaiseEx(TengShaderPartElse.GetTokenName);
  148. if aParent.HasParent(TengShaderPartIf, true) then
  149. RaiseEx(TengShaderPartIf.GetTokenName);
  150. if aParent.HasParent(TengShaderPartClass, true) then
  151. RaiseEx(TengShaderPartClass.GetTokenName);
  152. end;
  153. end.