瀏覽代碼

* startet implementation of code generator

master
Bergmann89 11 年之前
父節點
當前提交
051fb9ffa5
共有 23 個文件被更改,包括 1266 次插入 和 362 次删除
  1. +70
    -0
      uengShaderCodePart.pas
  2. +1
    -1
      uengShaderFile.old.pas
  3. +46
    -19
      uengShaderFile.pas
  4. +2
    -1
      uengShaderFileConstants.pas
  5. +16
    -5
      uengShaderFileExpression.pas
  6. +146
    -22
      uengShaderFileHelper.pas
  7. +8
    -1
      uengShaderFileTypes.pas
  8. +28
    -34
      uengShaderGenerator.pas
  9. +396
    -0
      uengShaderGeneratorArgs.pas
  10. +10
    -203
      uengShaderPart.pas
  11. +12
    -1
      uengShaderPartCall.pas
  12. +46
    -9
      uengShaderPartClass.pas
  13. +36
    -8
      uengShaderPartCntr.pas
  14. +1
    -1
      uengShaderPartComment.pas
  15. +36
    -2
      uengShaderPartEcho.pas
  16. +42
    -34
      uengShaderPartIf.pas
  17. +15
    -1
      uengShaderPartInclude.pas
  18. +80
    -11
      uengShaderPartKeyValuePair.pas
  19. +137
    -4
      uengShaderPartMessage.pas
  20. +23
    -1
      uengShaderPartMeta.pas
  21. +65
    -1
      uengShaderPartParameter.pas
  22. +17
    -2
      uengShaderPartScope.pas
  23. +33
    -1
      uengShaderPartText.pas

+ 70
- 0
uengShaderCodePart.pas 查看文件

@@ -0,0 +1,70 @@
unit uengShaderCodePart;

{$mode objfpc}{$H+}
{$I uengShaderFile.inc}

interface

uses
Classes, SysUtils,
uengShaderPart, uengShaderFileParser, uengShaderGeneratorArgs

{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;

type
TengShaderCodePart = class(TengShaderPart)
{ Code Loading & Storage }
protected
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; virtual;
public
function ParseText(const aArgs: TengParseArgs): String;

{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); virtual;
end;
CengShaderCodePart = class of TengShaderCodePart;
TengShaderCodePartList = specialize TutlSimpleList<TengShaderCodePart>;

implementation

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderCodePart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodePart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin
result := ''; // DUMMY
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodePart.ParseText(const aArgs: TengParseArgs): String;
var
params: TengTokenParameterList;
begin
params := TengTokenParameterList.Create(Filename);
try
fCol := aArgs.Col;
fLine := aArgs.Line;
if (GetTokenName <> '') then
aArgs.ExtractToken(self, params);
result := ParseIntern(aArgs, params);
finally
FreeAndNil(params);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodePart.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var
s: String;
begin
s := GetTokenName;
if (s <> '') then
aArgs.AddToken(s);
end;

end.


+ 1
- 1
uengShaderFile.old.pas 查看文件

@@ -295,7 +295,7 @@ type
ffInherited, // search in inherited classes (this is not a new recursion level!) ffInherited, // search in inherited classes (this is not a new recursion level!)
ffFile, // search in file that belongs to this class (this is not a new recursion level!) ffFile, // search in file that belongs to this class (this is not a new recursion level!)


// file
// file GenCodeIntern
ffIgnoreClasses // ignore class parts ffIgnoreClasses // ignore class parts
); );
TengFindMappedPartFlags = set of TengFindMappedPartFlag; TengFindMappedPartFlags = set of TengFindMappedPartFlag;


+ 46
- 19
uengShaderFile.pas 查看文件

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


uses uses
Classes, sysutils, Classes, sysutils,
uengShaderPart, uengShaderPartClass, uengShaderCodeGenerator, uengShaderFileParser, uengShaderFileTypes
uengShaderPart, uengShaderPartClass, uengShaderFileParser, uengShaderFileTypes,
uengShaderGenerator, uengShaderGeneratorArgs


{$IFDEF USE_BITSPACE_UTILS} {$IFDEF USE_BITSPACE_UTILS}
, uutlSerialization , uutlSerialization
@@ -43,6 +44,10 @@ type
procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil); procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil); procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
private private
fOnLog: TengShaderFileLogEvent; fOnLog: TengShaderFileLogEvent;
@@ -62,7 +67,7 @@ type
implementation implementation


uses uses
uengShaderPartInclude, uengShaderPartKeyValuePair;
uengShaderPartInclude, uengShaderPartKeyValuePair, uengShaderFileHelper;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -111,15 +116,19 @@ procedure TengShaderFile.UpdateClasses;


var var
sr: TengSearchResults; sr: TengSearchResults;
walker: TengSearchWalker;
p: TengShaderPart; p: TengShaderPart;
begin begin
sr := TengSearchResults.Create([TengShaderPartClass]);
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
try try
Find([sfSearchChildren], sr);
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartClass);
walker.SearchFlags := [sfSearchChildren];
fClasses.Clear; fClasses.Clear;
for p in sr.GetReverseEnumerator do
for p in sr do
AddClass(p as TengShaderPartClass); AddClass(p as TengShaderPartClass);
finally finally
FreeAndNil(walker);
FreeAndNil(sr); FreeAndNil(sr);
end; end;
end; end;
@@ -150,25 +159,29 @@ end;
procedure TengShaderFile.UpdateProperties; procedure TengShaderFile.UpdateProperties;
var var
sr: TengSearchResults; sr: TengSearchResults;
walker: TengSearchWalker;
p: TengShaderPart; p: TengShaderPart;
begin begin
inherited UpdateProperties; inherited UpdateProperties;


sr := TengSearchResults.Create([TengShaderFile]);
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
try try
Find(SEARCH_FLAG_FILE_PROPERTIES, sr);
for p in sr.GetReverseEnumerator do
walker.Owner := self;
walker.SearchFlags := [sfSearchChildren, sfIgnoreOwner];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderFile);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderCodeGenerator);
walker.Run(self);
for p in sr do
(p as TengShaderFile).CopyProperties(self); (p as TengShaderFile).CopyProperties(self);
finally
FreeAndNil(sr);
end;


sr := TengSearchResults.Create([TengShaderPartProperty]);
try
Find(SEARCH_FLAG_FILE_PROPERTIES, sr);
for p in sr.GetReverseEnumerator do
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty);
sr.Clear;
walker.Run(self);
for p in sr do
AddProperty(p as TengShaderPartProperty); AddProperty(p as TengShaderPartProperty);
finally finally
FreeAndNil(walker);
FreeAndNil(sr); FreeAndNil(sr);
end; end;
end; end;
@@ -203,6 +216,7 @@ begin
FreeAndNil(args); FreeAndNil(args);
end; end;
finally finally
FreeAndNil(ms);
fFileReader := nil; fFileReader := nil;
end; end;
end; end;
@@ -210,10 +224,11 @@ end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter); procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
var var
sr: TengSearchResults;
i: Integer; i: Integer;
sr: TengSearchResults;
sl: TStringList; sl: TStringList;
ms: TMemoryStream; ms: TMemoryStream;
walker: TengSearchWalker;
begin begin
fFileWriter := aFileWriter; fFileWriter := aFileWriter;
if not Assigned(fFileWriter) then if not Assigned(fFileWriter) then
@@ -221,11 +236,13 @@ begin
if not Assigned(fFileWriter) then if not Assigned(fFileWriter) then
fFileWriter := TengShaderFileWriter.Create; fFileWriter := TengShaderFileWriter.Create;


sr := TengSearchResults.Create([TengShaderPartInclude]);
sr := TengSearchResults.Create;
sl := TStringList.Create; sl := TStringList.Create;
ms := TMemoryStream.Create; ms := TMemoryStream.Create;
walker := TengSearchWalker.Create(sr);
try try
Find([sfSearchChildren, sfChildrenOnlyFile], sr);
walker.SearchFlags := [sfSearchChildren];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartInclude);
for i := 0 to sr.Count-1 do for i := 0 to sr.Count-1 do
(sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter); (sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
sl.Text := Text; sl.Text := Text;
@@ -233,6 +250,7 @@ begin
ms.Position := 0; ms.Position := 0;
fFileWriter.SaveStream(aFilename, ms); fFileWriter.SaveStream(aFilename, ms);
finally finally
FreeAndNil(walker);
FreeAndNil(sr); FreeAndNil(sr);
FreeAndNil(sl); FreeAndNil(sl);
FreeAndNil(ms); FreeAndNil(ms);
@@ -240,6 +258,15 @@ begin
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
if (aArgs.Root = self) then begin
// TODO generate main routine code (if exists)
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); procedure TengShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
var var
@@ -271,9 +298,9 @@ end;
destructor TengShaderFile.Destroy; destructor TengShaderFile.Destroy;
begin begin
FreeAndNil(fClasses); FreeAndNil(fClasses);
inherited Destroy;
fFileReader := nil; fFileReader := nil;
fFileWriter := nil; fFileWriter := nil;
inherited Destroy;
end; end;


end. end.


+ 2
- 1
uengShaderFileConstants.pas 查看文件

@@ -54,9 +54,10 @@ const
TOKEN_ELSE = TOKEN_CHAR_IDENT + 'ELSE'; TOKEN_ELSE = TOKEN_CHAR_IDENT + 'ELSE';
TOKEN_END = TOKEN_CHAR_IDENT + 'END'; TOKEN_END = TOKEN_CHAR_IDENT + 'END';


TOKEN_MESSAGE = TOKEN_CHAR_IDENT + 'MESSAGE'; //{$MESSAGE 'message'}
TOKEN_INFO = TOKEN_CHAR_IDENT + 'INFO'; //{$INFO 'message'}
TOKEN_WARNING = TOKEN_CHAR_IDENT + 'WARNING'; //{$WARNING 'message'} TOKEN_WARNING = TOKEN_CHAR_IDENT + 'WARNING'; //{$WARNING 'message'}
TOKEN_ERROR = TOKEN_CHAR_IDENT + 'ERROR'; //{$ERROR 'message'} TOKEN_ERROR = TOKEN_CHAR_IDENT + 'ERROR'; //{$ERROR 'message'}
TOKEN_THROW = TOKEN_CHAR_IDENT + 'THROW'; //{$THROW 'message'}


TOKEN_OP_LOGICAL_NOT = TOKEN_CHAR_IDENT + 'NOT'; //{$IF $NOT test} TOKEN_OP_LOGICAL_NOT = TOKEN_CHAR_IDENT + 'NOT'; //{$IF $NOT test}
TOKEN_OP_LOGICAL_OR = TOKEN_CHAR_IDENT + 'OR'; //{$IF test1 $OR test2} TOKEN_OP_LOGICAL_OR = TOKEN_CHAR_IDENT + 'OR'; //{$IF test1 $OR test2}


+ 16
- 5
uengShaderFileExpression.pas 查看文件

@@ -133,7 +133,7 @@ type
implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartScope, uengShaderFile;


const const
EXPRESSION_UNARY_OPERATIONS: array[TengExpressionUnaryOperator] of String = ( EXPRESSION_UNARY_OPERATIONS: array[TengExpressionUnaryOperator] of String = (
@@ -236,7 +236,9 @@ end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionVariable.GetValue: Variant; function TengExpressionVariable.GetValue: Variant;
begin begin
result := Unassigned; // TODO
result := Unassigned;
if Assigned(fPart) then
result := fPart.Value;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -642,7 +644,8 @@ var
bOp: TengExpressionBinaryOperator; bOp: TengExpressionBinaryOperator;
item: TengExpressionItem; item: TengExpressionItem;
param: TengTokenParameter; param: TengTokenParameter;
sr: TkvpSearchResults;
sr: TengSearchResults;
walker: TengKeyValuePairSearchWalker;
tmp: TengShaderPart; tmp: TengShaderPart;
begin begin
item := nil; item := nil;
@@ -686,12 +689,20 @@ begin
end else if IsValidIdentifier(param.Name) then begin end else if IsValidIdentifier(param.Name) then begin
if not (exVariable in aExpected) then if not (exVariable in aExpected) then
RaiseEx('unexpected variable:', param); RaiseEx('unexpected variable:', param);
sr := TkvpSearchResults.Create(param.Name, true, true);
sr := TengSearchResults.Create;
walker := TengKeyValuePairSearchWalker.Create(sr);
try try
fParent.Find(SEARCH_FLAG_CURRENT_SCOPE, sr);
walker.Name := param.Name;
walker.SearchFlags := [sfSearchChildrenLazy, sfSearchParents];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
walker.Run(fParent);
tmp := ExtractSearchResult(fParent, param.Name, sr, param.Line, param.Col); tmp := ExtractSearchResult(fParent, param.Name, sr, param.Line, param.Col);
result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col); result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col);
finally finally
FreeAndNil(walker);
FreeAndNil(sr); FreeAndNil(sr);
end; end;




+ 146
- 22
uengShaderFileHelper.pas 查看文件

@@ -13,13 +13,56 @@ function CheckEndToken(const aArgs: TengParseArgs; const aShaderPart: TengShader
function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; aLine: Integer = -1; aCol: Integer = -1; aFilename: String = ''): TengShaderPart; function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; aLine: Integer = -1; aCol: Integer = -1; aFilename: String = ''): TengShaderPart;


type type
TkvpSearchResults = class(TengSearchResults)
TengSearchFlag = (
sfSearchChildren, // search in children
sfSearchChildrenLazy, // set sfSearchChildren in next recursion level
sfSearchParents, // search in Parents
sfIgnoreOwner // ignore owner of search walker
);
TengSearchFlags = set of TengSearchFlag;

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

TengSearchWalker = class(TengShaderPartWalker)
private type
TArgs = packed record
Flags: TengSearchFlags;
end;
PArgs = ^TArgs;
private
fOwner: TengShaderPart;
fResults: TengSearchResults;
fSearchFlags: TengSearchFlags;
fResultTypes: CengShaderPartArr;
fChildrenDoNotLeave: CengShaderPartArr;
fParentsDoNotLeave: CengShaderPartArr;
fChildrenForceLeave: CengShaderPartArr;
fParentsForceLeave: CengShaderPartArr;
protected
procedure Visit(const aPart, aSender: TengShaderPart; const aArgs: Pointer); override;
function Check(const aPart: TengShaderPart): Boolean; virtual;
public
property Owner: TengShaderPart read fOwner write fOwner;
property SearchFlags: TengSearchFlags read fSearchFlags write fSearchFlags;
property ResultTypes: CengShaderPartArr read fResultTypes write fResultTypes;
property ChildrenDoNotLeave: CengShaderPartArr read fChildrenDoNotLeave write fChildrenDoNotLeave;
property ParentsDoNotLeave: CengShaderPartArr read fParentsDoNotLeave write fParentsDoNotLeave;
property ChildrenForceLeave: CengShaderPartArr read fChildrenForceLeave write fChildrenForceLeave;
property ParentsForceLeave: CengShaderPartArr read fParentsForceLeave write fParentsForceLeave;

constructor Create(const aResults: TengSearchResults);
end;

TengKeyValuePairSearchWalker = class(TengSearchWalker)
private private
fName: String; fName: String;
protected protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; override;
function Check(const aPart: TengShaderPart): Boolean; override;
public public
constructor Create(const aName: String; const aSearchDefines, aSearchProperties: Boolean);
property Name: String read fName write fName;
end; end;


implementation implementation
@@ -81,41 +124,122 @@ begin
end; end;
if (aList.Count <= 0) then if (aList.Count <= 0) then
raise EengUnknownIdentifier.Create(aIdent, aLine, aCol, aFilename, aSender); raise EengUnknownIdentifier.Create(aIdent, aLine, aCol, aFilename, aSender);
result := aList[0];
result := aList[aList.Count-1];
if (aList.Count > 1) and Assigned(aSender) then begin if (aList.Count > 1) and Assigned(aSender) then begin
s := Format('use of duplicate identifier: %s (%s %d:%d)', [aIdent, aList[0].Filename, aList[0].Line + 1, aList[0].Col]) + sLineBreak +
s := Format('use of duplicate identifier: %s (%s %d:%d)', [aIdent, result.Filename, result.Line + 1, result.Col]) + sLineBreak +
'previously declared here:' + sLineBreak; 'previously declared here:' + sLineBreak;
i := 1;
while (i < aList.Count) do begin
i := aList.Count - 2;
while (i >= 0) do begin
s := s + Format(' %s %d:%d', [aList[i].Filename, aList[i].Line + 1, aList[i].Col]) + sLineBreak; s := s + Format(' %s %d:%d', [aList[i].Filename, aList[i].Line + 1, aList[i].Col]) + sLineBreak;
inc(i);
dec(i);
end; end;
aSender.LogMsg(llWarning, s); aSender.LogMsg(llWarning, s);
end; end;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TkvpSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TkvpSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean;
constructor TengSearchResults.Create;
begin begin
result := inherited CheckObj(aPart, aContinue);
if result then
result := ((aPart as TengShaderPartKeyValuePair).Name = fName);
inherited Create(false);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TkvpSearchResults.Create(const aName: String; const aSearchDefines, aSearchProperties: Boolean);
//TengSearchWalker//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengSearchWalker.Visit(const aPart, aSender: TengShaderPart; const aArgs: Pointer);
var
args: TArgs;

function VisitChild(const aItem: TengShaderPart): Boolean;
var
c: CengShaderPart;
begin
result := (sfSearchChildren in args.Flags) and Assigned(aItem) and (aItem <> aSender);
if not result then
exit;
for c in fChildrenDoNotLeave do
if (aItem is c) then
result := false;
for c in fChildrenForceLeave do
if (aItem is c) then
result := true;
end;

function VisitParent: Boolean;
var
c: CengShaderPart;
begin
result := (sfSearchParents in args.Flags) and Assigned(aPart.Parent) and (aPart.Parent <> aSender);
if not result then
exit;
for c in fParentsDoNotLeave do
if (aPart is c) then
result := false;
for c in fParentsForceLeave do
if (aPart is c) then
result := true;
end;

var
c: TengShaderPart;
nextArgs: TArgs;
begin begin
if aSearchDefines and aSearchProperties then
inherited Create([TengShaderPartStatic, TengShaderPartProperty])
else if aSearchDefines then
inherited Create([TengShaderPartStatic])
else if aSearchProperties then
inherited Create([TengShaderPartProperty])
if not Assigned(aPart) then
exit;
if Assigned(aArgs) then
args := PArgs(aArgs)^
else else
inherited Create([]);
fName := aName;
args.Flags := fSearchFlags;

nextArgs := args;
if (sfSearchChildrenLazy in nextArgs.Flags) then
nextArgs.Flags := nextArgs.Flags + [sfSearchChildren] - [sfSearchChildrenLazy];
if Check(aPart.Parent) then
fResults.Add(aPart.Parent);
if VisitParent then
Visit(aPart.Parent, aPart, @nextArgs);

if (sfSearchChildren in args.Flags) then begin
for c in aPart do begin
if Check(c) then
fResults.Add(c);
if VisitChild(c) then
Visit(c, aPart, @args);
end;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengSearchWalker.Check(const aPart: TengShaderPart): Boolean;
var
c: CengShaderPart;
begin
result := (aPart <> fOwner) or not (sfIgnoreOwner in fSearchFlags);
if result then
for c in fResultTypes do
if (aPart is c) then
exit;
result := false;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengSearchWalker.Create(const aResults: TengSearchResults);
begin
inherited Create;
fResults := aResults;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengKeyValuePairSearchWalker//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengKeyValuePairSearchWalker.Check(const aPart: TengShaderPart): Boolean;
begin
result :=
inherited Check(aPart) and
(aPart is TengShaderPartKeyValuePair) and
((aPart as TengShaderPartKeyValuePair).Name = fName);
end; end;


end. end.


+ 8
- 1
uengShaderFileTypes.pas 查看文件

@@ -24,11 +24,18 @@ type
{$ENDIF} {$ENDIF}


TengShaderPartLogLevel = ( TengShaderPartLogLevel = (
llDebug,
llInfo, llInfo,
llWarning, llWarning,
llError
llError,
llThrow
); );


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderCode = class(TStringList)

end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Exceptions//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //Exceptions////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


uengShaderCodeGenerator.pas → uengShaderGenerator.pas 查看文件

@@ -1,4 +1,4 @@
unit uengShaderCodeGenerator;
unit uengShaderGenerator;


{$mode objfpc}{$H+} {$mode objfpc}{$H+}
{$I uengShaderFile.inc} {$I uengShaderFile.inc}
@@ -7,28 +7,15 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser, uengShaderPartScope, uengShaderPartKeyValuePair

{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;
uengShaderPart, uengShaderFileTypes, uengShaderFileParser, uengShaderPartScope,
uengShaderPartKeyValuePair, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderCodeGenerator = class(TengShaderPartScope) TengShaderCodeGenerator = class(TengShaderPartScope)
{ Code Loading & Storage } { Code Loading & Storage }
protected type
TPropertyList = class(specialize TutlSimpleList<TengShaderPartProperty>)
private
fValue: Variant;
public
property Value: Variant read fValue write fValue;
constructor Create;
end;
TPropertyMap = specialize TutlMap<string, TPropertyList>;
private private
fPropertyMap: TPropertyMap;
fPropertyMap: TengShaderPartPropertyMap;


function GetPropertyByIndex(const aIndex: Integer): Variant; function GetPropertyByIndex(const aIndex: Integer): Variant;
function GetPropertyByName(const aName: String): Variant; function GetPropertyByName(const aName: String): Variant;
@@ -48,6 +35,10 @@ type
property PropertyNames [const aIndex: Integer]: String read GetPropertyNames; property PropertyNames [const aIndex: Integer]: String read GetPropertyNames;
property PropertyCount: Integer read GetPropertyCount; property PropertyCount: Integer read GetPropertyCount;


{ Generate Shader Code }
public
procedure GenerateCode(const aCode: TengShaderCode);

{ General } { General }
public public
constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
@@ -56,17 +47,6 @@ type


implementation implementation


uses
uengShaderFileTypes;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderCodeGenerator.TPropertyList/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderCodeGenerator.TPropertyList.Create;
begin
inherited Create(false);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderCodeGenerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderCodeGenerator///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -78,7 +58,7 @@ end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodeGenerator.GetPropertyByName(const aName: String): Variant; function TengShaderCodeGenerator.GetPropertyByName(const aName: String): Variant;
var var
l: TPropertyList;
l: TengShaderPartPropertyList;
begin begin
l := fPropertyMap[aName]; l := fPropertyMap[aName];
if not Assigned(l) then if not Assigned(l) then
@@ -107,7 +87,7 @@ end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.SetPropertyByName(const aName: String; aValue: Variant); procedure TengShaderCodeGenerator.SetPropertyByName(const aName: String; aValue: Variant);
var var
l: TPropertyList;
l: TengShaderPartPropertyList;
begin begin
l := fPropertyMap[aName]; l := fPropertyMap[aName];
if not Assigned(l) then if not Assigned(l) then
@@ -118,7 +98,7 @@ end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean); procedure TengShaderCodeGenerator.AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean);
var var
l: TPropertyList;
l: TengShaderPartPropertyList;
p: TengShaderPartProperty; p: TengShaderPartProperty;
s: String; s: String;
begin begin
@@ -132,7 +112,7 @@ begin
LogMsg(llWarning, s); LogMsg(llWarning, s);
end; end;
end else begin end else begin
l := TPropertyList.Create;
l := TengShaderPartPropertyList.Create;
fPropertyMap.Add(aProp.Name, l); fPropertyMap.Add(aProp.Name, l);
end; end;
l.Add(aProp); l.Add(aProp);
@@ -143,7 +123,7 @@ end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.CopyProperties(const aGen: TengShaderCodeGenerator); procedure TengShaderCodeGenerator.CopyProperties(const aGen: TengShaderCodeGenerator);
var var
l: TPropertyList;
l: TengShaderPartPropertyList;
p: TengShaderPartProperty; p: TengShaderPartProperty;
begin begin
for l in fPropertyMap do for l in fPropertyMap do
@@ -164,11 +144,25 @@ begin
UpdateProperties; UpdateProperties;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.GenerateCode(const aCode: TengShaderCode);
var
args: TengShaderGeneratorArgs;
begin
args := TengShaderGeneratorArgs.Create(self);
try
inherited GenerateCodeIntern(args);
args.GenerateCode(aCode);
finally
FreeAndNil(args);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderCodeGenerator.Create(const aParent: TengShaderPart); constructor TengShaderCodeGenerator.Create(const aParent: TengShaderPart);
begin begin
inherited Create(aParent); inherited Create(aParent);
fPropertyMap := TPropertyMap.Create(true);
fPropertyMap := TengShaderPartPropertyMap.Create(true);
end; end;


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

+ 396
- 0
uengShaderGeneratorArgs.pas 查看文件

@@ -0,0 +1,396 @@
unit uengShaderGeneratorArgs;

{$mode objfpc}{$H+}
{$I uengShaderFile.inc}

interface

uses
Classes, SysUtils,
uengShaderFileTypes, uengShaderPart

{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengGenerateFlag = (
gfGenerateParameterItemCode, // generate code for parameter items
gfAddParameterItem // add parameter items to generator args
);
TengGenerateFlags = set of TengGenerateFlag;
TengShaderGeneratorArgs = class(TObject)
private type
TengGeneratorToken = (
gtNormal, // normal text
gtLineBreak, // line break
gtCommandEnd, // command end (like ';')
gtBlockBegin, // code block begin (to calculate indent)
gtBlockEnd, // code block end (to calculate indent)
gtToken // code token (like '$INCLUDE' or '$IF')
);

TCodePart = class(TObject)
private
fText: String;
fToken: TengGeneratorToken;
function GetText: String;
public
property Text: String read GetText;
property Token: TengGeneratorToken read fToken;
constructor Create(const aToken: TengGeneratorToken; const aText: String);
end;
TCodePartList = specialize TutlSimpleList<TCodePart>;

TCodeStackItem = class(TObject)
private
fItems: TCodePartList;
function GetIsEmpty: Boolean;
public
property Items: TCodePartList read fItems;
property IsEmpty: Boolean read GetIsEmpty;

procedure GenerateCode(const aCode: TengShaderCode);

constructor Create;
destructor Destroy; override;
end;
TCodeStack = specialize TutlSimpleList<TCodeStackItem>;

private
fCode: TCodeStack;
fRoot: TengShaderPart;
fFlags: TengGenerateFlags;

public
property Root: TengShaderPart read fRoot;
property Flags: TengGenerateFlags read fFlags;

procedure PushCode;
procedure PopCode;

procedure AddText(const aText: String);
procedure AddToken(const aToken: String);
procedure AddCommandEnd(const aToken: String);
procedure AddLineBreak;
procedure BeginBlock;
procedure EndBlock;

procedure AddMeta(const aMeta: TengShaderPart);
procedure AddParam(const aParam: TengShaderPart);

procedure GenerateCode(const aCode: TengShaderCode);

constructor Create(const aRoot: TengShaderPart);
destructor Destroy; override;
end;

implementation

uses
Math;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderGeneratorArgs.TCodePart///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderGeneratorArgs.TCodePart.GetText: String;
begin
case fToken of
gtNormal,
gtCommandEnd:
result := fText;
gtLineBreak:
result := sLineBreak;
else
result := '';
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderGeneratorArgs.TCodePart.Create(const aToken: TengGeneratorToken; const aText: String);
begin
inherited Create;
fToken := aToken;
fText := aText;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderGeneratorArgs.TCodeStackItem//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderGeneratorArgs.TCodeStackItem.GetIsEmpty: Boolean;
begin
result := (fItems.Count = 0);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.TCodeStackItem.GenerateCode(const aCode: TengShaderCode);
type
TGenFlag = (
gfToken, // current line has a token in it
gfTokenOnly, // current line has only a token (or whitespaces) in it
gfPrevIsEmpty, // previouse line was empty (or whitespaces only)
gfCodeIsEmpty, // nothing has added to code
gfAddToPrevLine, // add current line to previous line
gfAddNextLine // add next line to current line (set gfAddToPrevLine on linebreak)
);
TGenFlags = set of TGenFlag;

const
WHITESPACES = [' ', #9];

var
i: Integer;
f: TGenFlags;
line: String;

function GetStrOffset(const aStr: String): Integer;
var
len: Integer;
begin
result := 0;
len := Length(aStr);
while (result < len) and (aStr[result+1] in WHITESPACES) do
inc(result);
end;

function GetOffset(const aCodePart: TCodePart): Integer;
begin
result := GetStrOffset(line);
end;

function GetMinOffset(aStartIndex: Integer): Integer;
begin
if (Trim(line) <> '')
then result := GetStrOffset(line)
else result := High(Integer);
while (aStartIndex < aCode.Count) do begin
if (Trim(aCode[aStartIndex]) <> '') then
result := Min(result, GetStrOffset(aCode[aStartIndex]));
inc(aStartIndex);
end;
if (result >= High(Integer)) then
result := -1;
end;

function TrimLeftLen(const aStr: String; aLen: Integer): String;
var
i, len: Integer;
begin
i := 1;
len := Length(aStr);
while (i <= len) and (aStr[i] in WHITESPACES) and (aLen > 0) do begin
inc(i);
dec(aLen);
end;
result := Copy(aStr, i, len - i + 1);
end;

function PrepareStr(const aStr: String; const aOffset: Integer): String;
begin
if (aOffset < 0)
then result := StringOfChar(' ', -aOffset) + aStr
else result := TrimLeftLen(aStr, aOffset);
end;

procedure IndentBlock(aStartIndex: Integer; const aIndent: Integer);
var
o: Integer;
begin
o := GetMinOffset(aStartIndex) - aIndent;
if (o <= 0) then
exit;
while (aStartIndex < aCode.Count) do begin
aCode[aStartIndex] := PrepareStr(aCode[aStartIndex], o);
inc(aStartIndex);
end;
line := PrepareStr(line, o);
end;

procedure ProgressBlock(const aIndent: Integer);
var
s: String;
cp: TCodePart;
FirstLineIndex: Integer;
begin
FirstLineIndex := aCode.Count;
while (i < fItems.Count) do begin
cp := fItems[i];
inc(i);

case cp.Token of
gtLineBreak: begin

// line has whitespaces only
if (Trim(line) = '') then begin
if (f * [gfToken, gfPrevIsEmpty] = []) then begin
aCode.Add(line);
Include(f, gfPrevIsEmpty);
end;
if not (gfTokenOnly in f) then
Exclude(f, gfAddToPrevLine);

// line has text
end else begin
if (gfAddToPrevLine in f) and not (gfCodeIsEmpty in f) then begin
aCode[aCode.Count-1] := aCode[aCode.Count-1] + TrimLeft(line)
end else begin
aCode.Add(line);
Exclude(f, gfPrevIsEmpty);
Exclude(f, gfCodeIsEmpty);
end;
Exclude(f, gfAddToPrevLine);
end;
Exclude(f, gfToken);
Exclude(f, gfTokenOnly);
if (gfAddNextLine in f) then begin
Exclude(f, gfAddNextLine);
Include(f, gfAddToPrevLine);
end;
line := '';
end;

gtToken: begin
Include(f, gfToken);
if (Trim(line) = '') then
Include(f, gfTokenOnly);
end;

gtBlockBegin: begin
if (Trim(line) <> '') then
Include(f, gfAddNextLine);
Include(f, gfPrevIsEmpty);
ProgressBlock(GetOffset(cp));
end;

gtBlockEnd: begin
if (Trim(line) = '') then
Include(f, gfAddToPrevLine);
IndentBlock(FirstLineIndex, aIndent);
exit;
end;

else
s := cp.GetText;
if (gfAddNextLine in f) and (Trim(s) <> '') then
Exclude(f, gfAddNextLine);
line := line + s;
end;
end;
end;

begin
i := 0;
f := [gfPrevIsEmpty, gfCodeIsEmpty];
line := '';
ProgressBlock(0);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderGeneratorArgs.TCodeStackItem.Create;
begin
inherited Create;
fItems := TCodePartList.Create(true);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderGeneratorArgs.TCodeStackItem.Destroy;
begin
FreeAndNil(fItems);
inherited Destroy;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderGeneratorArgs/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PushCode;
begin
fCode.PushLast(TCodeStackItem.Create);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.PopCode;
var
csi: TCodeStackItem;
begin
csi := fCode.PopLast(false);
try
// TODO merge
finally
FreeAndNil(csi);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.AddText(const aText: String);
begin
fCode.Last.Items.Add(TCodePart.Create(gtNormal, aText));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.AddToken(const aToken: String);
begin
fCode.Last.Items.Add(TCodePart.Create(gtToken, aToken));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.AddCommandEnd(const aToken: String);
begin
fCode.Last.Items.Add(TCodePart.Create(gtCommandEnd, aToken));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.AddLineBreak;
begin
fCode.Last.Items.Add(TCodePart.Create(gtLineBreak, ''));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.BeginBlock;
begin
fCode.Last.Items.Add(TCodePart.Create(gtBlockBegin, ''));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.EndBlock;
begin
fCode.Last.Items.Add(TCodePart.Create(gtBlockEnd, ''));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.AddMeta(const aMeta: TengShaderPart);
begin
// TODO
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.AddParam(const aParam: TengShaderPart);
begin
// TODO
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderGeneratorArgs.GenerateCode(const aCode: TengShaderCode);
begin
fCode.Last.GenerateCode(aCode);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderGeneratorArgs.Create(const aRoot: TengShaderPart);
begin
inherited Create;
fCode := TCodeStack.Create(true);
fRoot := aRoot;
PushCode;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderGeneratorArgs.Destroy;
begin
FreeAndNil(fCode);
inherited Destroy;
end;

end.


+ 10
- 203
uengShaderPart.pas 查看文件

@@ -17,78 +17,18 @@ uses
{$ENDIF} {$ENDIF}
; ;


type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengSearchFlag = (
sfEvaluateIf, // evaluate if statements before search and process with suitable subtree
sfSearchAllIf, // search in all if sub trees

sfSearchPrevOnly, // search in previous items only
sfSearchInherited, // search in inherited

sfSearchChildren, // search in children
sfSearchChildrenLazy, // set sfSearchChildren in next recursion level
sfChildrenOnlyFile, // do not leave current file when searching for children
sfChildrenOnlyClass, // do not leave current class when searching for children
sfChildrenOnlyGenerator, // do not leave current generator when searching for children
sfChildrenOnlyScope, // do not leave current scope when searching for children
sfChildrenForceFile, // overwrite sfChildrenOnlyXXX flag when item is a file
sfChildrenForceClass, // overwrite sfChildrenOnlyXXX flag when item is a class
sfChildrenForceGenerator, // overwrite sfChildrenOnlyXXX flag when item is a generator
sfChildrenForceScope, // overwrite sfChildrenOnlyXXX flag when item is a scope

sfSearchParents, // search in Parents
sfParentsOnlyFile, // do not leave current file when searching in parents
sfParentsOnlyClass, // do not leave current class when searching in parents
sfParentsOnlyGenerator, // do not leave current generator when searching in parents
sfParentsOnlyScope, // do not leave current scope when searching in parents
sfParentsForceFile, // overwrite sfParentsOnlyXXX flag when item is a file
sfParentsForceClass, // overwrite sfParentsOnlyXXX flag when item is a class
sfParentsForceGenerator, // overwrite sfParentsOnlyXXX flag when item is a generator
sfParentsForceScope // overwrite sfParentsOnlyXXX flag when item is a scope
);
TengSearchFlags = set of TengSearchFlag;

const
SEARCH_FLAG_CURRENT_SCOPE = [
sfSearchPrevOnly,
sfSearchInherited,
sfSearchChildrenLazy,
sfChildrenOnlyScope,
sfChildrenForceFile,
sfSearchParents,
sfParentsOnlyFile
];
SEARCH_FLAG_CLASS_PROPERTIES = [
sfSearchAllIf,
sfSearchChildren,
sfChildrenOnlyGenerator,
sfChildrenForceFile
];
SEARCH_FLAG_FILE_PROPERTIES = [
sfSearchAllIf,
sfSearchChildren,
sfChildrenOnlyGenerator
];

type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPart = class; TengShaderPart = class;
CengShaderPart = class of TengShaderPart; CengShaderPart = class of TengShaderPart;
CengShaderPartArr = array of CengShaderPart;
TengShaderPartList = specialize TutlSimpleList<TengShaderPart>; TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;


TengSearchResults = class(specialize TutlList<TengShaderPart>)
private
fFirstOnly: Boolean;
fIgnore: TengShaderPart;
fTypes: array of CengShaderPart;
TengShaderPartWalker = class(TObject)
protected protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; virtual;
procedure Visit(const aPart, aCaller: TengShaderPart; const aArgs: Pointer); virtual;
public public
property FirstOnly: Boolean read fFirstOnly write fFirstOnly;
property Ignore: TengShaderPart read fIgnore write fIgnore;
function Add(const aPart: TengShaderPart): Boolean; reintroduce;
constructor Create(const aTypes: array of CengShaderPart);
procedure Run(const aPart: TengShaderPart);
end; end;


TengShaderPart = class(TIntfObjNoRefCount) TengShaderPart = class(TIntfObjNoRefCount)
@@ -123,7 +63,6 @@ type


{ General } { General }
protected protected
function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean; virtual;
procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); virtual; procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); virtual;
public { general methods } public { general methods }
property Root: TengShaderPart read fRoot; property Root: TengShaderPart read fRoot;
@@ -143,7 +82,6 @@ type
function GetParent(const aType: CengShaderPart; out aPart): Boolean; function GetParent(const aType: CengShaderPart; out aPart): Boolean;
function GetParent(const aType: CengShaderPart): TengShaderPart; function GetParent(const aType: CengShaderPart): TengShaderPart;


procedure Find(const aFlags: TengSearchFlags; const aResults: TengSearchResults);
procedure PrintTrace(const aPrefix: String; const aLines: TStrings); procedure PrintTrace(const aPrefix: String; const aLines: TStrings);
procedure LogMsg(const aLogLevel: TengShaderPartLogLevel; const aMsg: String); procedure LogMsg(const aLogLevel: TengShaderPartLogLevel; const aMsg: String);


@@ -159,19 +97,10 @@ type
class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual; class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual;
end; end;


TengShaderCodePart = class(TengShaderPart)
{ Code Loading & Storage }
protected
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; virtual;
public
function ParseText(const aArgs: TengParseArgs): String;
end;
CengShaderCodePart = class of TengShaderCodePart;

implementation implementation


uses uses
uengShaderPartScope, uengShaderCodeGenerator, uengShaderPartClass, uengShaderFile, uengShaderFileConstants;
uengShaderFileConstants;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TEnumerator//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPart.TEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -208,40 +137,17 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartWalker//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean;
var
c: CengShaderPart;
procedure TengShaderPartWalker.Visit(const aPart, aCaller: TengShaderPart; const aArgs: Pointer);
begin begin
aContinue := not fFirstOnly or (Count = 0);;
if aContinue then begin
result := (Length(fTypes) = 0);
for c in fTypes do
result := result or (aPart is c);
result := result and (aPart <> fIgnore);
end else
result := false;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengSearchResults.Add(const aPart: TengShaderPart): Boolean;
begin
result := true;
if result and CheckObj(aPart, result) then
inherited Add(aPart);
// DUMMY
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengSearchResults.Create(const aTypes: array of CengShaderPart);
var
i: Integer;
procedure TengShaderPartWalker.Run(const aPart: TengShaderPart);
begin begin
inherited Create(false);
fFirstOnly := false;
SetLength(fTypes, Length(aTypes));
for i := Low(fTypes) to High(fTypes) do
fTypes[i] := aTypes[i];
Visit(aPart, nil, nil);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -288,74 +194,6 @@ begin
else result := nil; else result := nil;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean;

function VisitChild(const aItem: TengShaderPart): Boolean;
begin
result := (sfSearchChildren in aFlags);
if not result then
exit;
result := result and
Assigned(aItem) and
(not (sfChildrenOnlyFile in aFlags) or not (aItem is TengShaderFile)) and
(not (sfChildrenOnlyClass in aFlags) or not (aItem is TengShaderPartClass)) and
(not (sfChildrenOnlyGenerator in aFlags) or not (aItem is TengShaderCodeGenerator)) and
(not (sfChildrenOnlyScope in aFlags) or not (aItem is TengShaderPartScope));
result := result or
((sfChildrenForceFile in aFlags) and (aItem is TengShaderFile)) or
((sfChildrenForceClass in aFlags) and (aItem is TengShaderPartClass)) or
((sfChildrenForceGenerator in aFlags) and (aItem is TengShaderCodeGenerator)) or
((sfChildrenForceScope in aFlags) and (aItem is TengShaderPartScope));
end;

function VisitParent: Boolean;
begin
result := (sfSearchParents in aFlags);
if not result then
exit;
result := result and
(not (sfParentsOnlyFile in aFlags) or not (self is TengShaderFile)) and
(not (sfParentsOnlyClass in aFlags) or not (self is TengShaderPartClass)) and
(not (sfParentsOnlyGenerator in aFlags) or not (self is TengShaderCodeGenerator)) and
(not (sfParentsOnlyScope in aFlags) or not (self is TengShaderPartScope));
result := result or
((sfParentsForceFile in aFlags) and (self is TengShaderFile)) or
((sfParentsForceClass in aFlags) and (self is TengShaderPartClass)) or
((sfParentsForceGenerator in aFlags) and (self is TengShaderCodeGenerator)) or
((sfParentsForceScope in aFlags) and (self is TengShaderPartScope));
end;

var
c: TengShaderPart;
b: Boolean;
begin
b := false;
result := true;
if (sfSearchChildren in aFlags) then begin
for c in self.GetReverseEnumerator do begin
b := b or (c = aChild);
if (sfSearchPrevOnly in aFlags) and not b then
continue;
if (c <> aChild) then begin
result := result and aResults.Add(c);
if VisitChild(c) then
result := result and c.FindIntern(aFlags - [sfSearchParents, sfSearchPrevOnly], nil, aResults);
end;
if not result then
exit;
end;
end;

if (sfSearchChildrenLazy in aFlags) then
aFlags := aFlags + [sfSearchChildren] - [sfSearchChildrenLazy];
if (sfSearchParents in aFlags) and Assigned(Parent) then begin
if VisitParent then
result := result and Parent.FindIntern(aFlags, self, aResults);
result := result and aResults.Add(Parent);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); procedure TengShaderPart.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
begin begin
@@ -391,12 +229,6 @@ begin
raise EengShaderPartInternal.Create(GetTokenName + ' ha sno parent of type ' + aType.GetTokenName, self); raise EengShaderPartInternal.Create(GetTokenName + ' ha sno parent of type ' + aType.GetTokenName, self);
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.Find(const aFlags: TengSearchFlags; const aResults: TengSearchResults);
begin
FindIntern(aFlags, nil, aResults);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.PrintTrace(const aPrefix: String; const aLines: TStrings); procedure TengShaderPart.PrintTrace(const aPrefix: String; const aLines: TStrings);


@@ -464,30 +296,5 @@ begin
// DUMMY // DUMMY
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderCodePart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodePart.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin
result := ''; // DUMMY
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodePart.ParseText(const aArgs: TengParseArgs): String;
var
params: TengTokenParameterList;
begin
params := TengTokenParameterList.Create(Filename);
try
fCol := aArgs.Col;
fLine := aArgs.Line;
if (GetTokenName <> '') then
aArgs.ExtractToken(self, params);
result := ParseIntern(aArgs, params);
finally
FreeAndNil(params);
end;
end;

end. end.



+ 12
- 1
uengShaderPartCall.pas 查看文件

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -20,6 +20,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
private private
function GetParameters: TStrings; function GetParameters: TStrings;
@@ -89,6 +93,13 @@ begin
fParameters.AddObject(aParams[i].Name, TObject(PtrInt(aParams[i].Quoted))); fParameters.AddObject(aParams[i].Name, TObject(PtrInt(aParams[i].Quoted)));
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCall.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
// TODO
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartCall.GetParameters: TStrings; function TengShaderPartCall.GetParameters: TStrings;
begin begin


+ 46
- 9
uengShaderPartClass.pas 查看文件

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderCodeGenerator, uengShaderFileParser
uengShaderPart, uengShaderGenerator, uengShaderGeneratorArgs, uengShaderFileParser


{$IFDEF USE_BITSPACE_UTILS} {$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics , uutlGenerics
@@ -32,6 +32,10 @@ type
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
procedure UpdateProperties; override; procedure UpdateProperties; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
public public
property Name: String read fName; property Name: String read fName;
@@ -50,7 +54,7 @@ type
implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartKeyValuePair;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartKeyValuePair, uengShaderPartScope, uengShaderFile;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartClass/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartClass///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -74,22 +78,35 @@ procedure TengShaderPartClass.UpdateInherited;
end; end;


var var
sr: TengSearchResults;
res: TengShaderPartList;
sr, res: TengSearchResults;
walker: TengSearchWalker;
s: String; s: String;
begin begin
if (fExtends.Count <= 0) then if (fExtends.Count <= 0) then
exit; exit;
sr := TengSearchResults.Create([TengShaderPartClass]);
res := TengShaderPartList.Create(false);
sr := TengSearchResults.Create;
res := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
try try
walker.Owner := self;
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartClass);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
walker.SearchFlags := [
sfIgnoreOwner,
sfSearchChildrenLazy,
sfSearchChildren,
sfSearchParents
];
fInherited.Clear; fInherited.Clear;
Find(SEARCH_FLAG_CURRENT_SCOPE, sr);
walker.Run(self);
for s in fExtends do begin for s in fExtends do begin
FilterResults(s, sr, res); FilterResults(s, sr, res);
fInherited.Add(ExtractSearchResult(self, s, res) as TengShaderPartClass); fInherited.Add(ExtractSearchResult(self, s, res) as TengShaderPartClass);
end; end;
finally finally
FreeAndNil(walker);
FreeAndNil(res); FreeAndNil(res);
FreeAndNil(sr); FreeAndNil(sr);
end; end;
@@ -143,6 +160,7 @@ end;
procedure TengShaderPartClass.UpdateProperties; procedure TengShaderPartClass.UpdateProperties;
var var
sr: TengSearchResults; sr: TengSearchResults;
walker: TengSearchWalker;
p: TengShaderPart; p: TengShaderPart;
c: TengShaderPartClass; c: TengShaderPartClass;
begin begin
@@ -151,16 +169,35 @@ begin
for c in fInherited do for c in fInherited do
c.CopyProperties(self); c.CopyProperties(self);


sr := TengSearchResults.Create([TengShaderPartProperty]);
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
try try
Find(SEARCH_FLAG_CLASS_PROPERTIES, sr);
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderCodeGenerator);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.Run(self);
for p in sr.GetReverseEnumerator do for p in sr.GetReverseEnumerator do
AddProperty(p as TengShaderPartProperty); AddProperty(p as TengShaderPartProperty);
finally finally
FreeAndNil(walker);
FreeAndNil(sr); FreeAndNil(sr);
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartClass.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var
c: TengShaderPartClass;
begin
if (aArgs.Root <> self) then
exit;
for c in fInherited do
c.GenerateCodeIntern(aArgs);
inherited GenerateCodeIntern(aArgs);

// TODO generate main routine
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartClass.Create(const aParent: TengShaderPart); constructor TengShaderPartClass.Create(const aParent: TengShaderPart);
begin begin


+ 36
- 8
uengShaderPartCntr.pas 查看文件

@@ -7,22 +7,28 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartCntr = class(TengShaderCodePart) TengShaderPartCntr = class(TengShaderCodePart)
{ Code Loading & Storage } { Code Loading & Storage }
private private
fChildren: TengShaderPartList;
procedure AddChild(const aChild: TengShaderPart; const aPrepend: Boolean = false);
fChildren: TengShaderCodePartList;
procedure AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean = false);
function HandleToken(const aToken: String; const aArgs: TengParseArgs): String; function HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
protected { virtual getter } protected { virtual getter }
function GetCount: Integer; override; function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override; function GetChild(const aIndex: Integer): TengShaderPart; override;
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
public { general methods }

{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General }
public
procedure Clear; virtual; procedure Clear; virtual;
constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override; destructor Destroy; override;
@@ -33,7 +39,11 @@ implementation
uses uses
uengShaderPartKeyValuePair, uengShaderPartClass, uengShaderPartMessage, uengShaderPartMeta, uengShaderPartKeyValuePair, uengShaderPartClass, uengShaderPartMessage, uengShaderPartMeta,
uengShaderPartCall, uengShaderPartProc, uengShaderPartText, uengShaderPartEcho, uengShaderPartIf, uengShaderPartCall, uengShaderPartProc, uengShaderPartText, uengShaderPartEcho, uengShaderPartIf,
uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment;
uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment, uengShaderFileConstants
{$IFDEF DEBUG}
, uengShaderFileTypes
{$ENDIF}
;


const const
TOKEN_CLASSES: array[0..21] of CengShaderCodePart = ( TOKEN_CLASSES: array[0..21] of CengShaderCodePart = (
@@ -51,7 +61,7 @@ const
TengShaderPartInclude, TengShaderPartInclude,
TengShaderPartInherited, TengShaderPartInherited,
TengShaderPartFunc, TengShaderPartFunc,
TengShaderPartMessage,
TengShaderPartInfo,
TengShaderPartMeta, TengShaderPartMeta,
TengShaderPartProc, TengShaderPartProc,
TengShaderPartProperty, TengShaderPartProperty,
@@ -64,7 +74,7 @@ const
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartCntr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartCntr////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCntr.AddChild(const aChild: TengShaderPart; const aPrepend: Boolean);
procedure TengShaderPartCntr.AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean);
begin begin
if aPrepend if aPrepend
then fChildren.PushFirst(aChild) then fChildren.PushFirst(aChild)
@@ -86,6 +96,10 @@ begin
break; break;
end; end;
end; end;
{$IFDEF DEBUG}
if Assigned(p) then
LogMsg(llDebug, 'ParseText: ' + p.ClassName);
{$ENDIF}
if Assigned(p) if Assigned(p)
then result := p.ParseText(aArgs) then result := p.ParseText(aArgs)
else result := aToken; else result := aToken;
@@ -136,6 +150,20 @@ begin
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCntr.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var
p: TengShaderCodePart;
begin
aArgs.AddToken(GetTokenName);
try
for p in fChildren do
p.GenerateCodeIntern(aArgs);
finally
aArgs.AddToken(TOKEN_END);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCntr.Clear; procedure TengShaderPartCntr.Clear;
begin begin
@@ -146,7 +174,7 @@ end;
constructor TengShaderPartCntr.Create(const aParent: TengShaderPart); constructor TengShaderPartCntr.Create(const aParent: TengShaderPart);
begin begin
inherited Create(aParent); inherited Create(aParent);
fChildren := TengShaderPartList.Create(true);
fChildren := TengShaderCodePartList.Create(true);
end; end;


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


+ 1
- 1
uengShaderPartComment.pas 查看文件

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderCodePart, uengShaderFileParser;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 36
- 2
uengShaderPartEcho.pas 查看文件

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderPartKeyValuePair, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -15,10 +15,15 @@ type
{ Code Loading & Storage } { Code Loading & Storage }
private private
fName: String; fName: String;
fValue: TengShaderPartKeyValuePair;
protected protected
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
@@ -27,7 +32,7 @@ type
implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartScope, uengShaderFile;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartEcho//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartEcho////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -39,6 +44,9 @@ end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartEcho.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartEcho.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
var
sr: TengSearchResults;
walker: TengKeyValuePairSearchWalker;
begin begin
if (aParams[0].Name <> GetTokenName) then with aParams[0] do if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self); raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
@@ -50,6 +58,32 @@ begin
raise EengInvalidIdentifier.Create(Name, self); raise EengInvalidIdentifier.Create(Name, self);
fName := Name; fName := Name;
end; end;
sr := TengSearchResults.Create;
walker := TengKeyValuePairSearchWalker.Create(sr);
try
walker.Name := fName;
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartProperty, TengShaderPartStatic);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
walker.SearchFlags := [
sfSearchChildrenLazy,
sfSearchChildren,
sfSearchParents
];
walker.Run(self);
fValue := (ExtractSearchResult(self, fName, sr) as TengShaderPartKeyValuePair);
finally
FreeAndNil(walker);
FreeAndNil(sr);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartEcho.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
aArgs.AddText(fValue.Value);
end; end;


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


+ 42
- 34
uengShaderPartIf.pas 查看文件

@@ -7,16 +7,23 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderPartScope, uengShaderFileExpression, uengShaderFileParser;
uengShaderPart, uengShaderCodePart, uengShaderPartScope, uengShaderFileExpression,
uengShaderFileParser, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartIf = class(TengShaderCodePart)
TengShaderPartIfCntr = class(TengShaderPartScope)
{ Class Methods }
public
class function GetTokenName: String; override;
end;

TengShaderPartIf = class(TengShaderPartIfCntr)
{ Code Loading & Storage } { Code Loading & Storage }
private private
fExpression: TengExpressionItem; fExpression: TengExpressionItem;
fIfPart: TengShaderCodePart;
fElsePart: TengShaderCodePart;
fIfPart: TengShaderPartScope;
fElsePart: TengShaderPartScope;
function HandleToken(const aToken: String; const aArgs: TengParseArgs): String; function HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
protected protected
function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; virtual; function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; virtual;
@@ -25,16 +32,17 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ General }
protected
function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean; override;
{ Code Generation }
public public
property Expression: TengExpressionItem read fExpression;
destructor Destroy; override;
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;


{ Class Methods }
{ General }
public public
class function GetTokenName: String; override;
property Expression: TengExpressionItem read fExpression;
property IfPart: TengShaderPartScope read fIfPart;
property ElsePart: TengShaderPartScope read fElsePart;

destructor Destroy; override;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -64,17 +72,27 @@ implementation
uses uses
uengShaderFileTypes, uengShaderFileConstants, uengShaderFileHelper; uengShaderFileTypes, uengShaderFileConstants, uengShaderFileHelper;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartIfCntr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartIfCntr.GetTokenName: String;
begin
result := TOKEN_IF;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartIf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartIf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartIf.HandleToken(const aToken: String; const aArgs: TengParseArgs): String; function TengShaderPartIf.HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
type
CengShaderPartScope = class of TengShaderPartScope;
const const
TOKEN_CLASSES: array[0..1] of CengShaderCodePart = (
TOKEN_CLASSES: array[0..1] of CengShaderPartScope = (
TengShaderPartElse, TengShaderPartElse,
TengShaderPartElIf TengShaderPartElIf
); );
var var
c: CengShaderCodePart;
c: CengShaderPartScope;
begin begin
for c in TOKEN_CLASSES do begin for c in TOKEN_CLASSES do begin
if c.CheckToken(aToken) then begin if c.CheckToken(aToken) then begin
@@ -132,27 +150,23 @@ begin


fExpression := ParseExpression(self, aParams, 1); fExpression := ParseExpression(self, aParams, 1);


fIfPart := TengShaderPartScope.Create(self);
fIfPart := TengShaderPartIfCntr.Create(self);
result := fIfPart.ParseText(aArgs); result := fIfPart.ParseText(aArgs);
result := HandleToken(result, aArgs); result := HandleToken(result, aArgs);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartIf.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean;
procedure TengShaderPartIf.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
var
b: Boolean;
p: TengShaderCodePart;
begin begin
result := true;
if (sfEvaluateIf in aFlags) and (sfSearchChildren in aFlags) then begin
if fExpression.GetValue then begin
if Assigned(fIfPart) then
fIfPart.Find(aFlags, aResults);
end else begin
if Assigned(fElsePart) then
fElsePart.Find(aFlags, aResults);
end;
end;
if not (sfSearchAllIf in aFlags) and (sfSearchChildren in aFlags) then
aFlags := aFlags - [sfSearchChildren] + [sfSearchChildrenLazy];
result := result and inherited FindIntern(aFlags, aChild, aResults);
b := fExpression.GetValue;
if b
then p := fIfPart
else p := fElsePart;
if Assigned(p) then
p.GenerateCodeIntern(aArgs);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -164,12 +178,6 @@ begin
inherited Destroy; inherited Destroy;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartIf.GetTokenName: String;
begin
result := TOKEN_IF;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartElIf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartElIf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 15
- 1
uengShaderPartInclude.pas 查看文件

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


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


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -24,6 +25,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
public public
property IncludeFile: String read fIncludeFile; property IncludeFile: String read fIncludeFile;
@@ -89,6 +94,15 @@ begin
LoadShaderFile; LoadShaderFile;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
LoadShaderFile;
inherited GenerateCodeIntern(aArgs);
if Assigned(fShaderFile) then
fShaderFile.GenerateCodeIntern(aArgs);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInclude.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter); procedure TengShaderPartInclude.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
begin begin


+ 80
- 11
uengShaderPartKeyValuePair.pas 查看文件

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


uses uses
Classes, SysUtils, variants, Classes, SysUtils, variants,
uengShaderPart, uengShaderFileParser;
uengShaderCodePart, uengShaderFileParser

{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
{$ENDIF}
;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -16,26 +21,47 @@ type
{ Code Loading & Storage } { Code Loading & Storage }
private private
fName: String; fName: String;
fValue: Variant;
fValueName: String; fValueName: String;
fDefaultValue: Variant;
protected protected
fValue: Variant;
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ General } { General }
public public
property Name: String read fName;
property Value: Variant read fValue;
property ValueName: String read fValueName;
property Name: String read fName;
property ValueName: String read fValueName;
property Value: Variant read fValue;
property DefaultValue: Variant read fDefaultValue;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartProperty = class(TengShaderPartKeyValuePair) TengShaderPartProperty = class(TengShaderPartKeyValuePair)
{ General }
public
property Value: Variant read fValue write fValue;

{ Class Methods } { Class Methods }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartPropertyList = class(specialize TutlSimpleList<TengShaderPartProperty>)
private
fValue: Variant;
public
property Value: Variant read fValue write fValue;
procedure ApplyValue;
constructor Create;
end;

TengShaderPartPropertyMap = class(specialize TutlMap<string, TengShaderPartPropertyList>)
public
procedure ApplyValues;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartStatic = class(TengShaderPartKeyValuePair) TengShaderPartStatic = class(TengShaderPartKeyValuePair)
{ Class Methods } { Class Methods }
@@ -46,7 +72,35 @@ type
implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderPart, uengShaderFile, uengShaderPartScope, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartPropertyList/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartPropertyList.ApplyValue;
var
p: TengShaderPartProperty;
begin
for p in self do
p.Value := fValue;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartPropertyList.Create;
begin
inherited Create(false);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartPropertyMap/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartPropertyMap.ApplyValues;
var
l: TengShaderPartPropertyList;
begin
for l in self do
l.ApplyValue;
end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartKeyValuePair//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartKeyValuePair////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -65,6 +119,7 @@ end;
function TengShaderPartKeyValuePair.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartKeyValuePair.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
var var
sr: TengSearchResults; sr: TengSearchResults;
walker: TengKeyValuePairSearchWalker;
begin begin
if (aParams[0].Name <> GetTokenName) then with aParams[0] do if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, GetTokenName, Line, Col, Filename, self); raise EengInvalidToken.Create(ClassName, GetTokenName, Line, Col, Filename, self);
@@ -77,15 +132,29 @@ begin
raise EengInvalidIdentifier.Create(fName, Line, Col, Filename, self); raise EengInvalidIdentifier.Create(fName, Line, Col, Filename, self);
if (aParams.Count >= 3) then if (aParams.Count >= 3) then
if aParams[2].Quoted then begin if aParams[2].Quoted then begin
fValue := aParams[2].Name;
fValueName := '';
fDefaultValue := aParams[2].Name;
fValue := fDefaultValue;
fValueName := '';
end else begin end else begin
fValueName := aParams[2].Name; fValueName := aParams[2].Name;
sr := TkvpSearchResults.Create(fValueName, true, false);
sr := TengSearchResults.Create;
walker := TengKeyValuePairSearchWalker.Create(sr);
try try
Find(SEARCH_FLAG_CURRENT_SCOPE, sr);
fValue := (ExtractSearchResult(self, fValueName, sr) as TengShaderPartStatic).Value;
walker.Name := fValueName;
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartStatic);
walker.ChildrenDoNotLeave := CengShaderPartArr.Create(TengShaderPartScope);
walker.ChildrenForceLeave := CengShaderPartArr.Create(TengShaderFile);
walker.ParentsDoNotLeave := CengShaderPartArr.Create(TengShaderFile);
walker.SearchFlags := [
sfSearchChildrenLazy,
sfSearchChildren,
sfSearchParents
];
walker.Run(self);
fDefaultValue := (ExtractSearchResult(self, fValueName, sr) as TengShaderPartStatic).Value;
fValue := fDefaultValue;
finally finally
FreeAndNil(walker);
FreeAndNil(sr); FreeAndNil(sr);
end; end;
end end


+ 137
- 4
uengShaderPartMessage.pas 查看文件

@@ -7,25 +7,158 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart;
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderFileTypes, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartMessage = class(TengShaderCodePart)
TengShaderPartInfo = class(TengShaderCodePart)
private
fMessage: String;


{ Code Loading & Storage }
protected
fLogLevel: TengShaderPartLogLevel;
function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;

{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General }
public
property Message: String read fMessage;
constructor Create(const aParent: TengShaderPart); override;

{ Class Methods }
public
class function GetTokenName: String; override;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartWarning = class(TengShaderPartMessage)
TengShaderPartWarning = class(TengShaderPartInfo)
{ General }
public
constructor Create(const aParent: TengShaderPart); override;


{ Class Methods }
public
class function GetTokenName: String; override;
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartError = class(TengShaderPartMessage)
TengShaderPartError = class(TengShaderPartInfo)
{ General }
public
constructor Create(const aParent: TengShaderPart); override;


{ Class Methods }
public
class function GetTokenName: String; override;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
EengShaderPartThrow = class(EengShaderPart);
TengShaderPartThrow = class(TengShaderPartInfo)
{ General }
public
constructor Create(const aParent: TengShaderPart); override;

{ Class Methods }
public
class function GetTokenName: String; override;
end; end;


implementation implementation


uses
uengShaderFileConstants;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartInfo/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartInfo.GetText: String;
begin
result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + TOKEN_CHAR_QUOTE + fMessage + TOKEN_CHAR_QUOTE + TOKEN_CHAR_END;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartInfo.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin
if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
if (aParams.Count <> 2) then
raise EengInvalidParamterCount.Create(GetTokenName, 2, self);
fMessage := aParams[1].Name;
result := inherited ParseIntern(aArgs, aParams);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartInfo.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
if (fLogLevel = llThrow)
then raise EengShaderPartThrow.Create(fMessage, self)
else LogMsg(fLogLevel, fMessage);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartInfo.Create(const aParent: TengShaderPart);
begin
inherited Create(aParent);
fLogLevel := llInfo;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartInfo.GetTokenName: String;
begin
result := TOKEN_INFO;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartWarning.Create(const aParent: TengShaderPart);
begin
inherited Create(aParent);
fLogLevel := llWarning;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartWarning/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartWarning.GetTokenName: String;
begin
result := TOKEN_WARNING;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartError.Create(const aParent: TengShaderPart);
begin
inherited Create(aParent);
fLogLevel := llError;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartError///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartError.GetTokenName: String;
begin
result := TOKEN_ERROR;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartThrow.Create(const aParent: TengShaderPart);
begin
inherited Create(aParent);
fLogLevel := llThrow;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartThrow///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartThrow.GetTokenName: String;
begin
result := TOKEN_THROW;
end;

end. end.



+ 23
- 1
uengShaderPartMeta.pas 查看文件

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -28,6 +28,8 @@ type
property Name: String read fName; property Name: String read fName;
property Values: TStrings read GetValues; property Values: TStrings read GetValues;


procedure Assign(const aValues: TengMetaData);

constructor Create(const aName: String; const aType: TengMetaType); constructor Create(const aName: String; const aType: TengMetaType);
destructor Destroy; override; destructor Destroy; override;
end; end;
@@ -41,6 +43,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
public public
property Data: TengMetaData read fData; property Data: TengMetaData read fData;
@@ -65,6 +71,15 @@ begin
result := fValues; result := fValues;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengMetaData.Assign(const aValues: TengMetaData);
begin
fName := aValues.Name;
fMetaType := aValues.MetaType;
fValues.Clear;
fValues.AddStrings(aValues.Values);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengMetaData.Create(const aName: String; const aType: TengMetaType); constructor TengMetaData.Create(const aName: String; const aType: TengMetaType);
begin begin
@@ -151,6 +166,13 @@ begin
end; end;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartMeta.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
aArgs.AddMeta(self);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartMeta.Create(const aParent: TengShaderPart); constructor TengShaderPartMeta.Create(const aParent: TengShaderPart);
begin begin


+ 65
- 1
uengShaderPartParameter.pas 查看文件

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser;
uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -20,6 +20,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
public public
property Name: String read fName; property Name: String read fName;
@@ -35,6 +39,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
public public
property DefaultValue: String read fDefaultValue; property DefaultValue: String read fDefaultValue;
@@ -46,6 +54,9 @@ type


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartVarying = class(TengShaderPartParameter) TengShaderPartVarying = class(TengShaderPartParameter)
{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;
{ Class Methods } { Class Methods }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
@@ -53,6 +64,10 @@ type


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartUniform = class(TengShaderPartParameter) TengShaderPartUniform = class(TengShaderPartParameter)
{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ Class Methods } { Class Methods }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
@@ -67,6 +82,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General } { General }
public public
property Value: String read fValue; property Value: String read fValue;
@@ -105,6 +124,15 @@ begin
fName := aParams[2].Name; fName := aParams[2].Name;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartParameter.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
if (gfAddParameterItem in aArgs.Flags) then begin
inherited GenerateCodeIntern(aArgs);
aArgs.AddParam(self);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartVar///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartVar/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -135,6 +163,15 @@ begin
fDefaultValue := ''; fDefaultValue := '';
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartVar.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
if (gfGenerateParameterItemCode in aArgs.Flags) then begin
// TODO
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartVar.GetTokenName: String; class function TengShaderPartVar.GetTokenName: String;
begin begin
@@ -143,6 +180,15 @@ end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartVarying///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartVarying/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartVarying.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
if (gfGenerateParameterItemCode in aArgs.Flags) then begin
// TODO
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartVarying.GetTokenName: String; class function TengShaderPartVarying.GetTokenName: String;
begin begin
@@ -151,6 +197,15 @@ end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartUniform///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartUniform/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartUniform.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
if (gfGenerateParameterItemCode in aArgs.Flags) then begin
// TODO
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartUniform.GetTokenName: String; class function TengShaderPartUniform.GetTokenName: String;
begin begin
@@ -183,6 +238,15 @@ begin
fValue := aParams[3].Name fValue := aParams[3].Name
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartConst.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
inherited GenerateCodeIntern(aArgs);
if (gfGenerateParameterItemCode in aArgs.Flags) then begin
// TODO
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartConst.GetTokenName: String; class function TengShaderPartConst.GetTokenName: String;
begin begin


+ 17
- 2
uengShaderPartScope.pas 查看文件

@@ -7,15 +7,30 @@ interface


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPartCntr;
uengShaderPartCntr, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartScope = class(TengShaderPartCntr) TengShaderPartScope = class(TengShaderPartCntr)

{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;
end; end;


implementation implementation


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartScope///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartScope.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
aArgs.BeginBlock;
try
inherited GenerateCodeIntern(aArgs);
finally
aArgs.EndBlock;
end;
end;

end. end.



+ 33
- 1
uengShaderPartText.pas 查看文件

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderFileParser;
uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -19,6 +19,12 @@ type
protected protected
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;

{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ General }
public public
property Text: String read fText; property Text: String read fText;
property IsEmpty: Boolean read GetIsEmpty; property IsEmpty: Boolean read GetIsEmpty;
@@ -31,6 +37,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ Class Methods } { Class Methods }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
@@ -45,6 +55,10 @@ type
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;


{ Code Generation }
public
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ Class Methods } { Class Methods }
public public
class function CheckToken(const aToken: String): Boolean; override; class function CheckToken(const aToken: String): Boolean; override;
@@ -88,6 +102,12 @@ begin
result := TOKEN_LINE_BREAK; result := TOKEN_LINE_BREAK;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartText.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
aArgs.AddText(fText);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartLineBreak/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartLineBreak///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -105,6 +125,12 @@ begin
result := ''; result := '';
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartLineBreak.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
aArgs.AddLineBreak;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartLineBreak.GetTokenName: String; class function TengShaderPartLineBreak.GetTokenName: String;
begin begin
@@ -127,6 +153,12 @@ begin
aArgs.NextCol; aArgs.NextCol;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartCommandEnd.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs);
begin
aArgs.AddCommandEnd(fToken);
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartCommandEnd.CheckToken(const aToken: String): Boolean; class function TengShaderPartCommandEnd.CheckToken(const aToken: String): Boolean;
var var


Loading…
取消
儲存