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.

178 rivejä
7.1 KiB

  1. unit uengShaderGenerator;
  2. {$mode objfpc}{$H+}
  3. {$I uengShaderFile.inc}
  4. interface
  5. uses
  6. Classes, SysUtils,
  7. uengShaderPart, uengShaderFileTypes, uengShaderFileParser, uengShaderPartScope,
  8. uengShaderPartKeyValuePair, uengShaderGeneratorArgs;
  9. type
  10. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  11. TengShaderGenerator = class(TengShaderPartScope)
  12. { Code Loading & Storage }
  13. private
  14. fPropertyMap: TengShaderPartPropertyMap;
  15. function GetPropertyByIndex(const aIndex: Integer): Variant;
  16. function GetPropertyByName(const aName: String): Variant;
  17. function GetPropertyCount: Integer;
  18. function GetPropertyNames(const aIndex: Integer): String;
  19. procedure SetPropertyByIndex(const aIndex: Integer; aValue: Variant);
  20. procedure SetPropertyByName(const aName: String; aValue: Variant);
  21. protected
  22. procedure AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean = true);
  23. procedure CopyProperties(const aGen: TengShaderGenerator);
  24. procedure UpdateProperties; virtual;
  25. function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
  26. public
  27. property PropertyByName [const aName: String]: Variant read GetPropertyByName write SetPropertyByName;
  28. property PropertyByIndex[const aIndex: Integer]: Variant read GetPropertyByIndex write SetPropertyByIndex;
  29. property PropertyNames [const aIndex: Integer]: String read GetPropertyNames;
  30. property PropertyCount: Integer read GetPropertyCount;
  31. { Generate Shader Code }
  32. public
  33. procedure GenerateCode(const aCode: TengShaderCode);
  34. { General }
  35. public
  36. constructor Create(const aParent: TengShaderPart); override;
  37. destructor Destroy; override;
  38. end;
  39. implementation
  40. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  41. //TengShaderGenerator///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  42. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  43. function TengShaderGenerator.GetPropertyByIndex(const aIndex: Integer): Variant;
  44. begin
  45. result := fPropertyMap.ValueAt[aIndex].Value;
  46. end;
  47. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  48. function TengShaderGenerator.GetPropertyByName(const aName: String): Variant;
  49. var
  50. l: TengShaderPartPropertyList;
  51. begin
  52. l := fPropertyMap[aName];
  53. if not Assigned(l) then
  54. EengUnknownIdentifier.Create(aName, self);
  55. result := l.Value;
  56. end;
  57. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  58. function TengShaderGenerator.GetPropertyCount: Integer;
  59. begin
  60. result := fPropertyMap.Count;
  61. end;
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. function TengShaderGenerator.GetPropertyNames(const aIndex: Integer): String;
  64. begin
  65. result := fPropertyMap.KeyValuePairs[aIndex].Key;
  66. end;
  67. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  68. procedure TengShaderGenerator.SetPropertyByIndex(const aIndex: Integer; aValue: Variant);
  69. begin
  70. fPropertyMap.ValueAt[aIndex].Value := aValue;
  71. end;
  72. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  73. procedure TengShaderGenerator.SetPropertyByName(const aName: String; aValue: Variant);
  74. var
  75. l: TengShaderPartPropertyList;
  76. begin
  77. l := fPropertyMap[aName];
  78. if not Assigned(l) then
  79. raise EengUnknownIdentifier.Create(aName, self);
  80. l.Value := aValue;
  81. end;
  82. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. procedure TengShaderGenerator.AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean);
  84. var
  85. l: TengShaderPartPropertyList;
  86. p: TengShaderPartProperty;
  87. s: String;
  88. begin
  89. l := fPropertyMap[aProp.Name];
  90. if Assigned(l) then begin
  91. if aShowWarning then begin
  92. p := l.Last;
  93. s := Format('use of duplicate identifier: %s (%s %d:%d)', [aProp.Name, aProp.Filename, aProp.Line + 1, aProp.Col]) + sLineBreak +
  94. 'previously declared here:' + sLineBreak +
  95. Format(' %s %d:%d', [p.Filename, p.Line + 1, p.Col]) + sLineBreak;
  96. LogMsg(llWarning, s);
  97. end;
  98. end else begin
  99. l := TengShaderPartPropertyList.Create;
  100. fPropertyMap.Add(aProp.Name, l);
  101. end;
  102. l.Add(aProp);
  103. if (aProp.Value <> Unassigned) then
  104. l.Value := aProp.Value;
  105. end;
  106. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  107. procedure TengShaderGenerator.CopyProperties(const aGen: TengShaderGenerator);
  108. var
  109. l: TengShaderPartPropertyList;
  110. p: TengShaderPartProperty;
  111. begin
  112. for l in fPropertyMap do
  113. for p in l do
  114. aGen.AddProperty(p, false);
  115. end;
  116. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  117. procedure TengShaderGenerator.UpdateProperties;
  118. begin
  119. fPropertyMap.Clear;
  120. end;
  121. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  122. function TengShaderGenerator.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
  123. begin
  124. result := inherited ParseIntern(aArgs, aParams);
  125. UpdateProperties;
  126. end;
  127. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  128. procedure TengShaderGenerator.GenerateCode(const aCode: TengShaderCode);
  129. var
  130. args: TengShaderGeneratorArgs;
  131. begin
  132. args := TengShaderGeneratorArgs.Create(self);
  133. try
  134. fPropertyMap.ApplyValues;
  135. GenerateCodeIntern(args);
  136. args.GenerateCode(aCode);
  137. finally
  138. FreeAndNil(args);
  139. end;
  140. end;
  141. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  142. constructor TengShaderGenerator.Create(const aParent: TengShaderPart);
  143. begin
  144. inherited Create(aParent);
  145. fPropertyMap := TengShaderPartPropertyMap.Create(true);
  146. end;
  147. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. destructor TengShaderGenerator.Destroy;
  149. begin
  150. FreeAndNil(fPropertyMap);
  151. inherited Destroy;
  152. end;
  153. end.