|
- unit uengShaderFile;
-
- { Package: SpaceEngine
- Prefix: eng - ENGine
- Beschreibung: stellt Klassen zum laden von Shader-Datein zur Verfügung
- beim laden des Codes wird gleichzeitig die Präprozessor-Sprache ausgewertet }
-
- {$mode objfpc}{$H+}
- {$I uengShaderFile.inc}
-
- interface
-
- uses
- Classes, sysutils,
- uengShaderPart, uengShaderPartClass, uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes
-
- {$IFDEF USE_BITSPACE_UTILS}
- , uutlSerialization
- {$ENDIF}
- ;
-
- type
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TengShaderFile = class(TengShaderCodeGenerator)
- { Code Loading & Storage }
- private
- fFilename: String;
- fFileReader: IutlFileReader;
- fFileWriter: IutlFileWriter;
- fClasses: TengShaderPartClassMap;
- private
- function GetGenerator(const aName: String): TengShaderCodeGenerator;
- function GetGeneratorCount: Integer;
- function GetGeneratorNames(const aIndex: Integer): String;
- protected
- function GetFilename: String; override;
- function GetFileReader: IengShaderFileReader; override;
- function GetFileWriter: IengShaderFileWriter; override;
-
- { General }
- private
- procedure UpdateClasses;
- protected
- procedure UpdateCache; override;
- public
- property Generator [const aName: String]: TengShaderCodeGenerator read GetGenerator;
- property GeneratorNames[const aIndex: Integer]: String read GetGeneratorNames;
- property GeneratorCount: Integer read GetGeneratorCount;
-
- procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
- procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
- procedure Clear; override;
- constructor Create(const aParent: TengShaderPart); override;
- destructor Destroy; override;
- end;
-
- implementation
-
- uses
- uengShaderPartInclude;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderFile.GetGenerator(const aName: String): TengShaderCodeGenerator;
- begin
- result := fClasses[aName];
- if not Assigned(result) then
- result := self;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderFile.GetGeneratorCount: Integer;
- begin
- result := fClasses.Count+1;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderFile.GetGeneratorNames(const aIndex: Integer): String;
- begin
- if (aIndex < 0) or (aIndex >= Count) then
- raise EengOutOfRange.Create(0, Count-1, aIndex, self);
- if (aIndex = 0)
- then result := ''
- else result := fClasses.Keys[aIndex-1];
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderFile.GetFilename: String;
- begin
- result := fFilename;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderFile.GetFileReader: IengShaderFileReader;
- begin
- result := fFileReader;
- if not Assigned(result) and Assigned(Parent) then
- result := Parent.FileReader;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderFile.GetFileWriter: IengShaderFileWriter;
- begin
- result := fFileWriter;
- if not Assigned(result) and Assigned(Parent) then
- result := Parent.FileWriter;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TengShaderFile.UpdateClasses;
- var
- sr: TengShaderPart.TSearchResults;
- p: TengShaderPart;
- new, old: TengShaderPartClass;
- begin
- sr := TengShaderPart.TSearchResults.Create([TengShaderPartClass]);
- try
- fClasses.Clear;
- Find([sfSearchChildren], sr);
- for p in sr do begin
- new := (p as TengShaderPartClass);
- old := fClasses[new.Name];
- if Assigned(old) then
- raise EengDuplicateIdentifier.Create(new.Name, new, old, self);
- fClasses.Add(new.Name, new);
- end;
- finally
- FreeAndNil(sr);
- end;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TengShaderFile.UpdateCache;
- begin
- inherited UpdateCache;
- UpdateClasses;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader);
- var
- args: TengParseArgs;
- token: String;
- ms: TMemoryStream;
- begin
- fFileReader := aFileReader;
- if not Assigned(fFileReader) then
- fFileReader := GetFileReader;
- if not Assigned(fFileReader) then
- fFileReader := TengShaderFileReader.Create;
- ms := TMemoryStream.Create;
- try
- Clear;
- if not fFileReader.LoadStream(aFilename, ms) then
- raise EengShaderPart.Create('unable to open file: ' + aFilename, Parent);
- ms.Position := 0;
- fFilename := aFilename;
- args := TengParseArgs.Create(ms, Filename);
- try
- token := ParseText(args);
- if (token <> '') then with args do
- raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self);
- if (Root = self) then
- UpdateCache;
- finally
- FreeAndNil(args);
- end;
- finally
- fFileReader := nil;
- end;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
- var
- sr: TengShaderPart.TSearchResults;
- i: Integer;
- sl: TStringList;
- ms: TMemoryStream;
- begin
- fFileWriter := aFileWriter;
- if not Assigned(fFileWriter) then
- fFileWriter := FileWriter;
- if not Assigned(fFileWriter) then
- fFileWriter := TengShaderFileWriter.Create;
-
- sr := TengShaderPart.TSearchResults.Create([TengShaderPartInclude]);
- sl := TStringList.Create;
- ms := TMemoryStream.Create;
- try
- Find([sfSearchChildren, sfChildrenFileOnly], sr);
- for i := 0 to sr.Count-1 do
- (sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
- sl.Text := Text;
- sl.SaveToStream(ms);
- ms.Position := 0;
- fFileWriter.SaveStream(aFilename, ms);
- finally
- FreeAndNil(sr);
- FreeAndNil(sl);
- FreeAndNil(ms);
- fFileWriter := nil;
- end;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TengShaderFile.Clear;
- begin
- inherited Clear;
- fClasses.Clear;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- constructor TengShaderFile.Create(const aParent: TengShaderPart);
- begin
- inherited Create(aParent);
- if not Assigned(fRoot) then
- fRoot := self;
- fClasses := TengShaderPartClassMap.Create(false);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- destructor TengShaderFile.Destroy;
- begin
- FreeAndNil(fClasses);
- fFileReader := nil;
- fFileWriter := nil;
- inherited Destroy;
- end;
-
- end.
|