Pārlūkot izejas kodu

* startet implementation of code generator

master
Bergmann89 pirms 9 gadiem
vecāks
revīzija
051fb9ffa5
23 mainītis faili ar 1266 papildinājumiem un 362 dzēšanām
  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 Parādīt failu

@@ -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 Parādīt failu

@@ -295,7 +295,7 @@ type
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!)

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


+ 46
- 19
uengShaderFile.pas Parādīt failu

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

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

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

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

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

uses
uengShaderPartInclude, uengShaderPartKeyValuePair;
uengShaderPartInclude, uengShaderPartKeyValuePair, uengShaderFileHelper;

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

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

sr := TengSearchResults.Create([TengShaderFile]);
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
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);
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);
finally
FreeAndNil(walker);
FreeAndNil(sr);
end;
end;
@@ -203,6 +216,7 @@ begin
FreeAndNil(args);
end;
finally
FreeAndNil(ms);
fFileReader := nil;
end;
end;
@@ -210,10 +224,11 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
var
sr: TengSearchResults;
i: Integer;
sr: TengSearchResults;
sl: TStringList;
ms: TMemoryStream;
walker: TengSearchWalker;
begin
fFileWriter := aFileWriter;
if not Assigned(fFileWriter) then
@@ -221,11 +236,13 @@ begin
if not Assigned(fFileWriter) then
fFileWriter := TengShaderFileWriter.Create;

sr := TengSearchResults.Create([TengShaderPartInclude]);
sr := TengSearchResults.Create;
sl := TStringList.Create;
ms := TMemoryStream.Create;
walker := TengSearchWalker.Create(sr);
try
Find([sfSearchChildren, sfChildrenOnlyFile], sr);
walker.SearchFlags := [sfSearchChildren];
walker.ResultTypes := CengShaderPartArr.Create(TengShaderPartInclude);
for i := 0 to sr.Count-1 do
(sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
sl.Text := Text;
@@ -233,6 +250,7 @@ begin
ms.Position := 0;
fFileWriter.SaveStream(aFilename, ms);
finally
FreeAndNil(walker);
FreeAndNil(sr);
FreeAndNil(sl);
FreeAndNil(ms);
@@ -240,6 +258,15 @@ begin
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);
var
@@ -271,9 +298,9 @@ end;
destructor TengShaderFile.Destroy;
begin
FreeAndNil(fClasses);
inherited Destroy;
fFileReader := nil;
fFileWriter := nil;
inherited Destroy;
end;

end.


+ 2
- 1
uengShaderFileConstants.pas Parādīt failu

@@ -54,9 +54,10 @@ const
TOKEN_ELSE = TOKEN_CHAR_IDENT + 'ELSE';
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_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_OR = TOKEN_CHAR_IDENT + 'OR'; //{$IF test1 $OR test2}


+ 16
- 5
uengShaderFileExpression.pas Parādīt failu

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

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

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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -642,7 +644,8 @@ var
bOp: TengExpressionBinaryOperator;
item: TengExpressionItem;
param: TengTokenParameter;
sr: TkvpSearchResults;
sr: TengSearchResults;
walker: TengKeyValuePairSearchWalker;
tmp: TengShaderPart;
begin
item := nil;
@@ -686,12 +689,20 @@ begin
end else if IsValidIdentifier(param.Name) then begin
if not (exVariable in aExpected) then
RaiseEx('unexpected variable:', param);
sr := TkvpSearchResults.Create(param.Name, true, true);
sr := TengSearchResults.Create;
walker := TengKeyValuePairSearchWalker.Create(sr);
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);
result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col);
finally
FreeAndNil(walker);
FreeAndNil(sr);
end;



+ 146
- 22
uengShaderFileHelper.pas Parādīt failu

@@ -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;

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
fName: String;
protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; override;
function Check(const aPart: TengShaderPart): Boolean; override;
public
constructor Create(const aName: String; const aSearchDefines, aSearchProperties: Boolean);
property Name: String read fName write fName;
end;

implementation
@@ -81,41 +124,122 @@ begin
end;
if (aList.Count <= 0) then
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
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;
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;
inc(i);
dec(i);
end;
aSender.LogMsg(llWarning, s);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TkvpSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TkvpSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean;
constructor TengSearchResults.Create;
begin
result := inherited CheckObj(aPart, aContinue);
if result then
result := ((aPart as TengShaderPartKeyValuePair).Name = fName);
inherited Create(false);
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
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
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.


+ 8
- 1
uengShaderFileTypes.pas Parādīt failu

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

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

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

end;

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


uengShaderCodeGenerator.pas → uengShaderGenerator.pas Parādīt failu

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

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

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderCodeGenerator = class(TengShaderPartScope)
{ 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
fPropertyMap: TPropertyMap;
fPropertyMap: TengShaderPartPropertyMap;

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

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

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

implementation

uses
uengShaderFileTypes;

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

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

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

+ 396
- 0
uengShaderGeneratorArgs.pas Parādīt failu

@@ -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 Parādīt failu

@@ -17,78 +17,18 @@ uses
{$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
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPart = class;
CengShaderPart = class of TengShaderPart;
CengShaderPartArr = array of CengShaderPart;
TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;

TengSearchResults = class(specialize TutlList<TengShaderPart>)
private
fFirstOnly: Boolean;
fIgnore: TengShaderPart;
fTypes: array of CengShaderPart;
TengShaderPartWalker = class(TObject)
protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; virtual;
procedure Visit(const aPart, aCaller: TengShaderPart; const aArgs: Pointer); virtual;
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;

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

{ General }
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;
public { general methods }
property Root: TengShaderPart read fRoot;
@@ -143,7 +82,6 @@ type
function GetParent(const aType: CengShaderPart; out aPart): Boolean;
function GetParent(const aType: CengShaderPart): TengShaderPart;

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

@@ -159,19 +97,10 @@ type
class procedure Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart); virtual;
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

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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -208,40 +137,17 @@ begin
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
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;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengSearchResults.Create(const aTypes: array of CengShaderPart);
var
i: Integer;
procedure TengShaderPartWalker.Run(const aPart: TengShaderPart);
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;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -288,74 +194,6 @@ begin
else result := nil;
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);
begin
@@ -391,12 +229,6 @@ begin
raise EengShaderPartInternal.Create(GetTokenName + ' ha sno parent of type ' + aType.GetTokenName, self);
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);

@@ -464,30 +296,5 @@ begin
// DUMMY
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.


+ 12
- 1
uengShaderPartCall.pas Parādīt failu

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

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

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

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

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

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

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


+ 46
- 9
uengShaderPartClass.pas Parādīt failu

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

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

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

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

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

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

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

var
sr: TengSearchResults;
res: TengShaderPartList;
sr, res: TengSearchResults;
walker: TengSearchWalker;
s: String;
begin
if (fExtends.Count <= 0) then
exit;
sr := TengSearchResults.Create([TengShaderPartClass]);
res := TengShaderPartList.Create(false);
sr := TengSearchResults.Create;
res := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
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;
Find(SEARCH_FLAG_CURRENT_SCOPE, sr);
walker.Run(self);
for s in fExtends do begin
FilterResults(s, sr, res);
fInherited.Add(ExtractSearchResult(self, s, res) as TengShaderPartClass);
end;
finally
FreeAndNil(walker);
FreeAndNil(res);
FreeAndNil(sr);
end;
@@ -143,6 +160,7 @@ end;
procedure TengShaderPartClass.UpdateProperties;
var
sr: TengSearchResults;
walker: TengSearchWalker;
p: TengShaderPart;
c: TengShaderPartClass;
begin
@@ -151,16 +169,35 @@ begin
for c in fInherited do
c.CopyProperties(self);

sr := TengSearchResults.Create([TengShaderPartProperty]);
sr := TengSearchResults.Create;
walker := TengSearchWalker.Create(sr);
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
AddProperty(p as TengShaderPartProperty);
finally
FreeAndNil(walker);
FreeAndNil(sr);
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);
begin


+ 36
- 8
uengShaderPartCntr.pas Parādīt failu

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartCntr = class(TengShaderCodePart)
{ Code Loading & Storage }
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;
protected { virtual getter }
function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override;
function GetText: 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;
constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override;
@@ -33,7 +39,11 @@ implementation
uses
uengShaderPartKeyValuePair, uengShaderPartClass, uengShaderPartMessage, uengShaderPartMeta,
uengShaderPartCall, uengShaderPartProc, uengShaderPartText, uengShaderPartEcho, uengShaderPartIf,
uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment;
uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment, uengShaderFileConstants
{$IFDEF DEBUG}
, uengShaderFileTypes
{$ENDIF}
;

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

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


+ 1
- 1
uengShaderPartComment.pas Parādīt failu

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

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

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


+ 36
- 2
uengShaderPartEcho.pas Parādīt failu

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -15,10 +15,15 @@ type
{ Code Loading & Storage }
private
fName: String;
fValue: TengShaderPartKeyValuePair;
protected
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
class function GetTokenName: String; override;
@@ -27,7 +32,7 @@ type
implementation

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

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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartEcho.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
var
sr: TengSearchResults;
walker: TengKeyValuePairSearchWalker;
begin
if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, Name, Line, Col, Filename, self);
@@ -50,6 +58,32 @@ begin
raise EengInvalidIdentifier.Create(Name, self);
fName := Name;
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;

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


+ 42
- 34
uengShaderPartIf.pas Parādīt failu

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

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

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

TengShaderPartIf = class(TengShaderPartIfCntr)
{ Code Loading & Storage }
private
fExpression: TengExpressionItem;
fIfPart: TengShaderCodePart;
fElsePart: TengShaderCodePart;
fIfPart: TengShaderPartScope;
fElsePart: TengShaderPartScope;
function HandleToken(const aToken: String; const aArgs: TengParseArgs): String;
protected
function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; virtual;
@@ -25,16 +32,17 @@ type
function GetText: 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
property Expression: TengExpressionItem read fExpression;
destructor Destroy; override;
procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override;

{ Class Methods }
{ General }
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;

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

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

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

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

fIfPart := TengShaderPartScope.Create(self);
fIfPart := TengShaderPartIfCntr.Create(self);
result := fIfPart.ParseText(aArgs);
result := HandleToken(result, aArgs);
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
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;

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

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

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


+ 15
- 1
uengShaderPartInclude.pas Parādīt failu

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -24,6 +25,10 @@ type
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 IncludeFile: String read fIncludeFile;
@@ -89,6 +94,15 @@ begin
LoadShaderFile;
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);
begin


+ 80
- 11
uengShaderPartKeyValuePair.pas Parādīt failu

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

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

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

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

{ General }
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;

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

{ Class Methods }
public
class function GetTokenName: String; override;
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)
{ Class Methods }
@@ -46,7 +72,35 @@ type
implementation

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////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -65,6 +119,7 @@ end;
function TengShaderPartKeyValuePair.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
var
sr: TengSearchResults;
walker: TengKeyValuePairSearchWalker;
begin
if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, GetTokenName, Line, Col, Filename, self);
@@ -77,15 +132,29 @@ begin
raise EengInvalidIdentifier.Create(fName, Line, Col, Filename, self);
if (aParams.Count >= 3) then
if aParams[2].Quoted then begin
fValue := aParams[2].Name;
fValueName := '';
fDefaultValue := aParams[2].Name;
fValue := fDefaultValue;
fValueName := '';
end else begin
fValueName := aParams[2].Name;
sr := TkvpSearchResults.Create(fValueName, true, false);
sr := TengSearchResults.Create;
walker := TengKeyValuePairSearchWalker.Create(sr);
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
FreeAndNil(walker);
FreeAndNil(sr);
end;
end


+ 137
- 4
uengShaderPartMessage.pas Parādīt failu

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

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

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;

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

{ Class Methods }
public
class function GetTokenName: String; override;
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;

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.


+ 23
- 1
uengShaderPartMeta.pas Parādīt failu

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

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

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

procedure Assign(const aValues: TengMetaData);

constructor Create(const aName: String; const aType: TengMetaType);
destructor Destroy; override;
end;
@@ -41,6 +43,10 @@ type
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 Data: TengMetaData read fData;
@@ -65,6 +71,15 @@ begin
result := fValues;
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);
begin
@@ -151,6 +166,13 @@ begin
end;
end;

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

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


+ 65
- 1
uengShaderPartParameter.pas Parādīt failu

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -20,6 +20,10 @@ type
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 Name: String read fName;
@@ -35,6 +39,10 @@ type
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 DefaultValue: String read fDefaultValue;
@@ -46,6 +54,9 @@ type

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

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

{ Class Methods }
public
class function GetTokenName: String; override;
@@ -67,6 +82,10 @@ type
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 Value: String read fValue;
@@ -105,6 +124,15 @@ begin
fName := aParams[2].Name;
end;

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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartVar/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -135,6 +163,15 @@ begin
fDefaultValue := '';
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;
begin
@@ -143,6 +180,15 @@ end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//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;
begin
@@ -151,6 +197,15 @@ end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//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;
begin
@@ -183,6 +238,15 @@ begin
fValue := aParams[3].Name
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;
begin


+ 17
- 2
uengShaderPartScope.pas Parādīt failu

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

uses
Classes, SysUtils,
uengShaderPartCntr;
uengShaderPartCntr, uengShaderGeneratorArgs;

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

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

implementation

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

end.


+ 33
- 1
uengShaderPartText.pas Parādīt failu

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -19,6 +19,12 @@ type
protected
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 Text: String read fText;
property IsEmpty: Boolean read GetIsEmpty;
@@ -31,6 +37,10 @@ type
function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;

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

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

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

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

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

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

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

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

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

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


Notiek ielāde…
Atcelt
Saglabāt