您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

183 行
7.4 KiB

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