Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

234 rindas
8.2 KiB

  1. unit uengShaderFile;
  2. { Package: SpaceEngine
  3. Prefix: eng - ENGine
  4. Beschreibung: stellt Klassen zum laden von Shader-Datein zur Verfügung
  5. beim laden des Codes wird gleichzeitig die Präprozessor-Sprache ausgewertet }
  6. {$mode objfpc}{$H+}
  7. {$I uengShaderFile.inc}
  8. interface
  9. uses
  10. Classes, sysutils,
  11. uengShaderPart, uengShaderPartClass, uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes
  12. {$IFDEF USE_BITSPACE_UTILS}
  13. , uutlSerialization
  14. {$ENDIF}
  15. ;
  16. type
  17. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  18. TengShaderFile = class(TengShaderCodeGenerator)
  19. { Code Loading & Storage }
  20. private
  21. fFilename: String;
  22. fFileReader: IutlFileReader;
  23. fFileWriter: IutlFileWriter;
  24. fClasses: TengShaderPartClassMap;
  25. private
  26. function GetGenerator(const aName: String): TengShaderCodeGenerator;
  27. function GetGeneratorCount: Integer;
  28. function GetGeneratorNames(const aIndex: Integer): String;
  29. protected
  30. function GetFilename: String; override;
  31. function GetFileReader: IengShaderFileReader; override;
  32. function GetFileWriter: IengShaderFileWriter; override;
  33. { General }
  34. private
  35. procedure UpdateClasses;
  36. protected
  37. procedure UpdateCache; override;
  38. public
  39. property Generator [const aName: String]: TengShaderCodeGenerator read GetGenerator;
  40. property GeneratorNames[const aIndex: Integer]: String read GetGeneratorNames;
  41. property GeneratorCount: Integer read GetGeneratorCount;
  42. procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
  43. procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
  44. procedure Clear; override;
  45. constructor Create(const aParent: TengShaderPart); override;
  46. destructor Destroy; override;
  47. end;
  48. implementation
  49. uses
  50. uengShaderPartInclude;
  51. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  52. //TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  53. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  54. function TengShaderFile.GetGenerator(const aName: String): TengShaderCodeGenerator;
  55. begin
  56. result := fClasses[aName];
  57. if not Assigned(result) then
  58. result := self;
  59. end;
  60. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  61. function TengShaderFile.GetGeneratorCount: Integer;
  62. begin
  63. result := fClasses.Count+1;
  64. end;
  65. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  66. function TengShaderFile.GetGeneratorNames(const aIndex: Integer): String;
  67. begin
  68. if (aIndex < 0) or (aIndex >= Count) then
  69. raise EengOutOfRange.Create(0, Count-1, aIndex, self);
  70. if (aIndex = 0)
  71. then result := ''
  72. else result := fClasses.Keys[aIndex-1];
  73. end;
  74. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. function TengShaderFile.GetFilename: String;
  76. begin
  77. result := fFilename;
  78. end;
  79. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  80. function TengShaderFile.GetFileReader: IengShaderFileReader;
  81. begin
  82. result := fFileReader;
  83. if not Assigned(result) and Assigned(Parent) then
  84. result := Parent.FileReader;
  85. end;
  86. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. function TengShaderFile.GetFileWriter: IengShaderFileWriter;
  88. begin
  89. result := fFileWriter;
  90. if not Assigned(result) and Assigned(Parent) then
  91. result := Parent.FileWriter;
  92. end;
  93. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  94. procedure TengShaderFile.UpdateClasses;
  95. var
  96. sr: TengShaderPart.TSearchResults;
  97. p: TengShaderPart;
  98. new, old: TengShaderPartClass;
  99. begin
  100. sr := TengShaderPart.TSearchResults.Create([TengShaderPartClass]);
  101. try
  102. fClasses.Clear;
  103. Find([sfSearchChildren], sr);
  104. for p in sr do begin
  105. new := (p as TengShaderPartClass);
  106. old := fClasses[new.Name];
  107. if Assigned(old) then
  108. raise EengDuplicateIdentifier.Create(new.Name, new, old, self);
  109. fClasses.Add(new.Name, new);
  110. end;
  111. finally
  112. FreeAndNil(sr);
  113. end;
  114. end;
  115. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  116. procedure TengShaderFile.UpdateCache;
  117. begin
  118. inherited UpdateCache;
  119. UpdateClasses;
  120. end;
  121. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  122. procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader);
  123. var
  124. args: TengParseArgs;
  125. token: String;
  126. ms: TMemoryStream;
  127. begin
  128. fFileReader := aFileReader;
  129. if not Assigned(fFileReader) then
  130. fFileReader := GetFileReader;
  131. if not Assigned(fFileReader) then
  132. fFileReader := TengShaderFileReader.Create;
  133. ms := TMemoryStream.Create;
  134. try
  135. Clear;
  136. if not fFileReader.LoadStream(aFilename, ms) then
  137. raise EengShaderPart.Create('unable to open file: ' + aFilename, Parent);
  138. ms.Position := 0;
  139. fFilename := aFilename;
  140. args := TengParseArgs.Create(ms, Filename);
  141. try
  142. token := ParseText(args);
  143. if (token <> '') then with args do
  144. raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self);
  145. if (Root = self) then
  146. UpdateCache;
  147. finally
  148. FreeAndNil(args);
  149. end;
  150. finally
  151. fFileReader := nil;
  152. end;
  153. end;
  154. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  155. procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
  156. var
  157. sr: TengShaderPart.TSearchResults;
  158. i: Integer;
  159. sl: TStringList;
  160. ms: TMemoryStream;
  161. begin
  162. fFileWriter := aFileWriter;
  163. if not Assigned(fFileWriter) then
  164. fFileWriter := FileWriter;
  165. if not Assigned(fFileWriter) then
  166. fFileWriter := TengShaderFileWriter.Create;
  167. sr := TengShaderPart.TSearchResults.Create([TengShaderPartInclude]);
  168. sl := TStringList.Create;
  169. ms := TMemoryStream.Create;
  170. try
  171. Find([sfSearchChildren, sfChildrenFileOnly], sr);
  172. for i := 0 to sr.Count-1 do
  173. (sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
  174. sl.Text := Text;
  175. sl.SaveToStream(ms);
  176. ms.Position := 0;
  177. fFileWriter.SaveStream(aFilename, ms);
  178. finally
  179. FreeAndNil(sr);
  180. FreeAndNil(sl);
  181. FreeAndNil(ms);
  182. fFileWriter := nil;
  183. end;
  184. end;
  185. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  186. procedure TengShaderFile.Clear;
  187. begin
  188. inherited Clear;
  189. fClasses.Clear;
  190. end;
  191. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  192. constructor TengShaderFile.Create(const aParent: TengShaderPart);
  193. begin
  194. inherited Create(aParent);
  195. if not Assigned(fRoot) then
  196. fRoot := self;
  197. fClasses := TengShaderPartClassMap.Create(false);
  198. end;
  199. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  200. destructor TengShaderFile.Destroy;
  201. begin
  202. FreeAndNil(fClasses);
  203. fFileReader := nil;
  204. fFileWriter := nil;
  205. inherited Destroy;
  206. end;
  207. end.