Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

217 righe
8.0 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. TengShaderFileLogEvent = procedure(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String) of object;
  19. TengShaderFile = class(TengShaderCodeGenerator)
  20. { Code Loading & Storage }
  21. private
  22. fFilename: String;
  23. fFileReader: IutlFileReader;
  24. fFileWriter: IutlFileWriter;
  25. fClasses: TengShaderPartClassMap;
  26. private
  27. function GetGenerator(const aName: String): TengShaderCodeGenerator;
  28. function GetGeneratorCount: Integer;
  29. function GetGeneratorNames(const aIndex: Integer): String;
  30. protected
  31. function GetFilename: String; override;
  32. function GetFileReader: IengShaderFileReader; override;
  33. function GetFileWriter: IengShaderFileWriter; override;
  34. public
  35. procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
  36. procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
  37. { General }
  38. private
  39. fOnLog: TengShaderFileLogEvent;
  40. protected
  41. procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); override;
  42. public
  43. property Generator [const aName: String]: TengShaderCodeGenerator read GetGenerator;
  44. property GeneratorNames[const aIndex: Integer]: String read GetGeneratorNames;
  45. property GeneratorCount: Integer read GetGeneratorCount;
  46. property OnLog: TengShaderFileLogEvent read fOnLog write fOnLog;
  47. procedure Clear; override;
  48. constructor Create(const aParent: TengShaderPart); override;
  49. destructor Destroy; override;
  50. end;
  51. implementation
  52. uses
  53. uengShaderPartInclude;
  54. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  55. //TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  56. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  57. function TengShaderFile.GetGenerator(const aName: String): TengShaderCodeGenerator;
  58. begin
  59. result := fClasses[aName];
  60. if not Assigned(result) then
  61. result := self;
  62. end;
  63. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  64. function TengShaderFile.GetGeneratorCount: Integer;
  65. begin
  66. result := fClasses.Count+1;
  67. end;
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. function TengShaderFile.GetGeneratorNames(const aIndex: Integer): String;
  70. begin
  71. if (aIndex < 0) or (aIndex >= Count) then
  72. raise EengOutOfRange.Create(0, Count-1, aIndex, self);
  73. if (aIndex = 0)
  74. then result := ''
  75. else result := fClasses.Keys[aIndex-1];
  76. end;
  77. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  78. function TengShaderFile.GetFilename: String;
  79. begin
  80. result := fFilename;
  81. end;
  82. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. function TengShaderFile.GetFileReader: IengShaderFileReader;
  84. begin
  85. result := fFileReader;
  86. if not Assigned(result) and Assigned(Parent) then
  87. result := Parent.FileReader;
  88. end;
  89. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  90. function TengShaderFile.GetFileWriter: IengShaderFileWriter;
  91. begin
  92. result := fFileWriter;
  93. if not Assigned(result) and Assigned(Parent) then
  94. result := Parent.FileWriter;
  95. end;
  96. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader);
  98. var
  99. args: TengParseArgs;
  100. token: String;
  101. ms: TMemoryStream;
  102. begin
  103. fFileReader := aFileReader;
  104. if not Assigned(fFileReader) then
  105. fFileReader := GetFileReader;
  106. if not Assigned(fFileReader) then
  107. fFileReader := TengShaderFileReader.Create;
  108. ms := TMemoryStream.Create;
  109. try
  110. Clear;
  111. if not fFileReader.LoadStream(aFilename, ms) then
  112. raise EengShaderPart.Create('unable to open file: ' + aFilename, Parent);
  113. ms.Position := 0;
  114. fFilename := aFilename;
  115. args := TengParseArgs.Create(ms, Filename);
  116. try
  117. token := ParseText(args);
  118. if (token <> '') then with args do
  119. raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self);
  120. finally
  121. FreeAndNil(args);
  122. end;
  123. finally
  124. fFileReader := nil;
  125. end;
  126. end;
  127. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  128. procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
  129. var
  130. sr: TengSearchResults;
  131. i: Integer;
  132. sl: TStringList;
  133. ms: TMemoryStream;
  134. begin
  135. fFileWriter := aFileWriter;
  136. if not Assigned(fFileWriter) then
  137. fFileWriter := FileWriter;
  138. if not Assigned(fFileWriter) then
  139. fFileWriter := TengShaderFileWriter.Create;
  140. sr := TengSearchResults.Create([TengShaderPartInclude]);
  141. sl := TStringList.Create;
  142. ms := TMemoryStream.Create;
  143. try
  144. Find([sfSearchChildren, sfChildrenOnlyFile], sr);
  145. for i := 0 to sr.Count-1 do
  146. (sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
  147. sl.Text := Text;
  148. sl.SaveToStream(ms);
  149. ms.Position := 0;
  150. fFileWriter.SaveStream(aFilename, ms);
  151. finally
  152. FreeAndNil(sr);
  153. FreeAndNil(sl);
  154. FreeAndNil(ms);
  155. fFileWriter := nil;
  156. end;
  157. end;
  158. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  159. procedure TengShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
  160. var
  161. tmp: TengShaderFileLogEvent;
  162. begin
  163. inherited LogMsgIntern(aSender, aLogLevel, aMsg);
  164. tmp := fOnLog;
  165. if Assigned(tmp) then
  166. tmp(aSender, aLogLevel, aMsg);
  167. end;
  168. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  169. procedure TengShaderFile.Clear;
  170. begin
  171. inherited Clear;
  172. fClasses.Clear;
  173. end;
  174. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  175. constructor TengShaderFile.Create(const aParent: TengShaderPart);
  176. begin
  177. inherited Create(aParent);
  178. if not Assigned(fRoot) then
  179. fRoot := self;
  180. fClasses := TengShaderPartClassMap.Create(false);
  181. end;
  182. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  183. destructor TengShaderFile.Destroy;
  184. begin
  185. FreeAndNil(fClasses);
  186. fFileReader := nil;
  187. fFileWriter := nil;
  188. inherited Destroy;
  189. end;
  190. end.