浏览代码

* implemented SaveToFile

master
Bergmann89 11 年前
父节点
当前提交
55407c60da
共有 5 个文件被更改,包括 212 次插入 和 26 次删除
  1. +67
    -5
      uengShaderFile.pas
  2. +22
    -18
      uengShaderFileParser.pas
  3. +6
    -0
      uengShaderFileTypes.pas
  4. +83
    -1
      uengShaderPart.pas
  5. +34
    -2
      uengShaderPartInclude.pas

+ 67
- 5
uengShaderFile.pas 查看文件

@@ -12,7 +12,7 @@ interface

uses
Classes, sysutils,
uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes
uengShaderPart, uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes

{$IFDEF USE_BITSPACE_UTILS}
, uutlSerialization
@@ -31,12 +31,21 @@ type
function GetFilename: String; override;
function GetFileReader: IengShaderFileReader; override;
function GetFileWriter: IengShaderFileWriter; override;
public { general methods }
procedure LoadCode(const aFilename: String; const aFileReader: IengShaderFileReader = nil);

{ General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); override;
public
procedure LoadFromFile(const aFilename: String; const aFlags: TengShaderFileLoadFlags = []; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
destructor Destroy; override;
end;

implementation

uses
uengShaderPartInclude;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -62,7 +71,16 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LoadCode(const aFilename: String; const aFileReader: IengShaderFileReader);
procedure TengShaderFile.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
begin
if (sfCurrentFileOnly in aFlags) then
exclude(aFlags, sfSearchParents);
inherited FindIntern(aFlags, aDepth, aTypes, aList);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFlags: TengShaderFileLoadFlags;
const aFileReader: IengShaderFileReader);
var
args: TengParseArgs;
token: String;
@@ -79,8 +97,10 @@ begin
if not fFileReader.LoadStream(aFilename, ms) then
raise EengShaderPart.Create('unable to open file: ' + aFilename, Line, Col, Filename);
ms.Position := 0;
fFilename := aFilename;
args := TengParseArgs.Create(ms, Filename);
try
args.Flags := aFlags;
token := ParseText(args);
if (token <> '') then with args do
raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename);
@@ -88,9 +108,51 @@ begin
FreeAndNil(args);
end;
finally
fFileReader := nil;
if not (lfLazyInclude in aFlags) then
fFileReader := nil;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
var
l: TengShaderPart.TSearchList;
i: Integer;
sl: TStringList;
ms: TMemoryStream;
begin
fFileWriter := aFileWriter;
if not Assigned(fFileWriter) then
fFileWriter := FileWriter;
if not Assigned(fFileWriter) then
fFileWriter := TengShaderFileWriter.Create;

l := TengShaderPart.TSearchList.Create;
sl := TStringList.Create;
ms := TMemoryStream.Create;
try
FindAll([sfSearchChildren, sfCurrentFileOnly], [TengShaderPartInclude], l);
for i := 0 to l.Count-1 do
(l[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
sl.Text := Text;
sl.SaveToStream(ms);
ms.Position := 0;
fFileWriter.SaveStream(aFilename, ms);
finally
FreeAndNil(l);
FreeAndNil(sl);
FreeAndNil(ms);
fFileWriter := nil;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderFile.Destroy;
begin
fFileReader := nil;
fFileWriter := nil;
inherited Destroy;
end;

end.


+ 22
- 18
uengShaderFileParser.pas 查看文件

@@ -6,7 +6,8 @@ unit uengShaderFileParser;
interface

uses
Classes, SysUtils
Classes, SysUtils,
uengShaderFileTypes

{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
@@ -36,6 +37,7 @@ type
private
fFilename: String;
fCode: TStringList;
fFlags: TengShaderFileLoadFlags;
fLineLength: Integer;
fLineCount: Integer;
fCurrentLine: String;
@@ -61,6 +63,8 @@ type
property Col: Integer read fCol write SetCol;
property Line: Integer read fLine write SetLine;

property Flags: TengShaderFileLoadFlags read fFlags write fFlags;

procedure NextCol;
procedure NextLine;
function ExtractToken(const aParameters: TengTokenParameterList): Boolean;
@@ -73,7 +77,7 @@ type
implementation

uses
uengShaderFileConstants, uengShaderFileTypes;
uengShaderFileConstants;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengTokenParameterList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -150,7 +154,7 @@ type
TParseFlags = set of TParseFlag;

var
flags: TParseFlags;
pf: TParseFlags;
ct: TCharType;
s: String;
pLine, pCol, oldLine, oldCol: Integer;
@@ -203,26 +207,26 @@ begin
ct := ctUnknown;
oldLine := Line;
oldCol := Col;
flags := [];
pf := [];
if (CurrentLine[Col+1] = TOKEN_CHAR_COMMENT) then
Include(flags, pfIsComment);
Include(pf, pfIsComment);
AddPart; // initialize

while not EndOfFile do begin
while not EndOfLine do begin
case CurrentChar of
TOKEN_CHAR_BEGIN: begin
if (pfQuote in flags) then
if (pfQuote in pf) then
s := s + CurrentChar
else if not (pfInToken in flags) then
Include(flags, pfInToken)
else if not (pfInToken in pf) then
Include(pf, pfInToken)
else
EengShaderPart.Create('invalid char in token', Line, Col, Filename);
end;

TOKEN_CHAR_END: begin
if not (pfQuote in flags) then begin
AddPart(not (pfIsComment in flags));
if not (pfQuote in pf) then begin
AddPart(not (pfIsComment in pf));
NextCol;
if (aParameters.Count <= 0) or (aParameters[0].Name = TOKEN_CHAR_IDENT) then
raise EengShaderPart.Create('empty token', Line, Col, Filename);
@@ -232,25 +236,25 @@ begin
end;

TOKEN_CHAR_QUOTE: begin
if not (pfQuote in flags) and not (pfIsComment in flags) then
if not (pfQuote in pf) and not (pfIsComment in pf) then
AddPart;
s := s + CurrentChar;
if (pfQuote in flags)
then exclude(flags, pfQuote)
else include(flags, pfQuote);
if not (pfQuote in flags) and not (pfIsComment in flags) then
if (pfQuote in pf)
then exclude(pf, pfQuote)
else include(pf, pfQuote);
if not (pfQuote in pf) and not (pfIsComment in pf) then
AddPart;
end;

TOKEN_CHAR_COMMENT: begin
s := s + CurrentChar;
if (pfIsComment in flags) and not (pfCommentTokenAdded in flags) then begin
include(flags, pfCommentTokenAdded);
if (pfIsComment in pf) and not (pfCommentTokenAdded in pf) then begin
include(pf, pfCommentTokenAdded);
AddPart(false);
end;
end;
else
if not (pfQuote in flags) and not (pfIsComment in flags) then begin
if not (pfQuote in pf) and not (pfIsComment in pf) then begin
if (CurrentChar in TOKEN_SPLIT_CHARS) then begin
AddPart;
end else if (CurrentChar in VALID_TOKEN_CHARS) then begin


+ 6
- 0
uengShaderFileTypes.pas 查看文件

@@ -23,6 +23,12 @@ type
TIntfObjNoRefCount = uutlCommon.TutlInterfaceNoRefCount;
{$ENDIF}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderFileLoadFlag = (
lfLazyInclude // include files will only be loaded when needed (this will store a reference to the passed IengShaderFileReader)
);
TengShaderFileLoadFlags = set of TengShaderFileLoadFlag;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengShaderPart = class(Exception)
public


+ 83
- 1
uengShaderPart.pas 查看文件

@@ -18,7 +18,18 @@ uses

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderFileSearchFlag = (
sfFirstOnly, // search first match only
sfEvaluateIf, // evaluate if statements before search and process with suitable subtree
sfSearchChildren, // search in children
sfSearchParents, // search in parents
sfCurrentFileOnly // do not search in other files
);
TengShaderFileSearchFlags = set of TengShaderFileSearchFlag;

TengShaderPart = class;
CengShaderPart = class of TengShaderPart;
TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;
TengShaderPart = class(TIntfObjNoRefCount)
{ Nested Types }
public type
@@ -33,6 +44,11 @@ type
constructor Create(const aOwner: TengShaderPart);
end;

TSearchList = class(TengShaderPartList)
public
constructor Create;
end;

{ Code Loading & Storage }
private { members }
fRoot: TengShaderPart;
@@ -52,6 +68,8 @@ type
function ParseText(const aArgs: TengParseArgs): String;

{ General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); virtual;
public { general methods }
property Root: TengShaderPart read fRoot;
property Parent: TengShaderPart read fParent;
@@ -68,6 +86,8 @@ type

function HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean = false): Boolean;
function GetParent(const aType: CengShaderPart; out aPart): Boolean;
function FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
procedure FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
function GetEnumerator: TEnumerator;

constructor Create(const aParent: TengShaderPart); virtual;
@@ -78,13 +98,25 @@ type
class function CheckToken(const aToken: String): Boolean; virtual;
class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual;
end;
TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;

implementation

uses
uengShaderFileConstants;

function CheckType(const aShaderPart: TengShaderPart; const aTypes: array of CengShaderPart): Boolean;
var
c: CengShaderPart;
begin
result := true;
if (Length(aTypes) = 0) then
exit;
for c in aTypes do
if (aShaderPart is c) then
exit;
result := false;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -108,6 +140,14 @@ begin
fPosition := -1;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TSearchList////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPart.TSearchList.Create;
begin
inherited Create(false);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -169,6 +209,26 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
var
c: TengShaderPart;
begin
if (sfFirstOnly in aFlags) and (aList.Count > 0) then
exit;

if CheckType(self, aTypes) then
aList.Add(self);

if (sfSearchChildren in aFlags) then begin
for c in self do
c.FindIntern(aFlags, aDepth+1, aTypes, aList);
end;

if (sfSearchParents in aFlags) and Assigned(Parent) then
Parent.FindIntern(aFlags, aDepth-1, aTypes, aList);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin
@@ -195,6 +255,28 @@ begin
result := false;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.FindFirst(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart): TengShaderPart;
var
l: TSearchList;
begin
l := TSearchList.Create;
try
FindIntern(aFlags + [sfFirstOnly], 0, aTypes, l);
if (l.Count > 0)
then result := l[0]
else result := nil;
finally
FreeAndNil(l);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.FindAll(const aFlags: TengShaderFileSearchFlags; const aTypes: array of CengShaderPart; const aList: TSearchList);
begin
FindIntern(aFlags, 0, aTypes, aList);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.GetEnumerator: TEnumerator;
begin


+ 34
- 2
uengShaderPartInclude.pas 查看文件

@@ -7,7 +7,7 @@ interface

uses
Classes, SysUtils,
uengShaderPart, uengShaderFile, uengShaderFileParser;
uengShaderPart, uengShaderFile, uengShaderFileParser, uengShaderFileTypes;

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -17,6 +17,7 @@ type
fShaderFile: TengShaderFile;
fIncludeFile: String;
fAbsoluteFile: String;
procedure LoadShaderFile(const aFlags: TengShaderFileLoadFlags);
protected
function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override;
@@ -24,8 +25,11 @@ type
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;

{ General }
protected
procedure FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList); override;
public
property IncludeFile: String read fIncludeFile;
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override;

@@ -38,10 +42,19 @@ implementation

uses
FileUtil,
uengShaderFileTypes, uengShaderFileConstants;
uengShaderFileConstants;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartInclude/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.LoadShaderFile(const aFlags: TengShaderFileLoadFlags);
begin
if not Assigned(fShaderFile) then
fShaderFile := TengShaderFile.Create(self);
if (fShaderFile.Filename <> fAbsoluteFile) then
fShaderFile.LoadFromFile(fAbsoluteFile, aFlags);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartInclude.GetCount: Integer;
begin
@@ -74,6 +87,25 @@ begin
fIncludeFile := aParams[1].Name;
fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(Filename));
result := '';
if not (lfLazyInclude in aArgs.Flags) then
LoadShaderFile(aArgs.Flags);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.FindIntern(aFlags: TengShaderFileSearchFlags; aDepth: Integer; aTypes: array of CengShaderPart; const aList: TSearchList);
begin
if (sfCurrentFileOnly in aFlags) then
exclude(aFlags, sfSearchChildren);
inherited FindIntern(aFlags, aDepth, aTypes, aList);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
begin
LoadShaderFile([]);
fIncludeFile := Format('%p_', [Pointer(fShaderFile)]) + ExtractFileName(fIncludeFile);
fAbsoluteFile := CreateAbsolutePath(fIncludeFile, ExtractFilePath(aFilename));
fShaderFile.SaveToFile(fAbsoluteFile, aFileWriter);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


正在加载...
取消
保存