Просмотр исходного кода

* completed implementation of code loading and storage

master
Bergmann89 11 лет назад
Родитель
Сommit
b441d27477
11 измененных файлов: 428 добавлений и 87 удалений
  1. +145
    -5
      uengShaderCodeGenerator.pas
  2. +65
    -1
      uengShaderFile.pas
  3. +2
    -2
      uengShaderFileConstants.pas
  4. +2
    -28
      uengShaderFileExpression.pas
  5. +37
    -3
      uengShaderFileHelper.pas
  6. +36
    -26
      uengShaderPart.pas
  7. +67
    -1
      uengShaderPartClass.pas
  8. +3
    -2
      uengShaderPartCntr.pas
  9. +5
    -5
      uengShaderPartIf.pas
  10. +15
    -13
      uengShaderPartKeyValuePair.pas
  11. +51
    -1
      uengShaderPartParameter.pas

+ 145
- 5
uengShaderCodeGenerator.pas Просмотреть файл

@@ -7,14 +7,48 @@ interface


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

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


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

function GetPropertyByIndex(const aIndex: Integer): Variant;
function GetPropertyByName(const aName: String): Variant;
function GetPropertyCount: Integer;
function GetPropertyNames(const aIndex: Integer): String;

procedure SetPropertyByIndex(const aIndex: Integer; aValue: Variant);
procedure SetPropertyByName(const aName: String; aValue: Variant);
protected
procedure AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean = true);
procedure CopyProperties(const aGen: TengShaderCodeGenerator);
procedure UpdateProperties; virtual;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
public
property PropertyByName [const aName: String]: Variant read GetPropertyByName write SetPropertyByName;
property PropertyByIndex[const aIndex: Integer]: Variant read GetPropertyByIndex write SetPropertyByIndex;
property PropertyNames [const aIndex: Integer]: String read GetPropertyNames;
property PropertyCount: Integer read GetPropertyCount;

{ General }
public public
constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override; destructor Destroy; override;
@@ -22,19 +56,125 @@ type


implementation implementation


uses
uengShaderFileTypes;

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

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderCodeGenerator/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderCodeGenerator///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodeGenerator.GetPropertyByIndex(const aIndex: Integer): Variant;
begin
result := fPropertyMap.ValueAt[aIndex].Value;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodeGenerator.GetPropertyByName(const aName: String): Variant;
var
l: TPropertyList;
begin
l := fPropertyMap[aName];
if not Assigned(l) then
EengUnknownIdentifier.Create(aName, self);
result := l.Value;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodeGenerator.GetPropertyCount: Integer;
begin
result := fPropertyMap.Count;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodeGenerator.GetPropertyNames(const aIndex: Integer): String;
begin
result := fPropertyMap.KeyValuePairs[aIndex].Key;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.SetPropertyByIndex(const aIndex: Integer; aValue: Variant);
begin
fPropertyMap.ValueAt[aIndex].Value := aValue;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.SetPropertyByName(const aName: String; aValue: Variant);
var
l: TPropertyList;
begin
l := fPropertyMap[aName];
if not Assigned(l) then
EengUnknownIdentifier.Create(aName, self);
l.Value := aValue;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.AddProperty(const aProp: TengShaderPartProperty; const aShowWarning: Boolean);
var
l: TPropertyList;
p: TengShaderPartProperty;
s: String;
begin
l := fPropertyMap[aProp.Name];
if Assigned(l) then begin
if aShowWarning then begin
p := l.Last;
s := Format('use of duplicate identifier: %s (%s %d:%d)', [aProp.Name, aProp.Filename, aProp.Line + 1, aProp.Col]) + sLineBreak +
'previously declared here:' + sLineBreak +
Format(' %s %d:%d', [p.Filename, p.Line + 1, p.Col]) + sLineBreak;
LogMsg(llWarning, s);
end;
end else begin
l := TPropertyList.Create;
fPropertyMap.Add(aProp.Name, l);
end;
l.Add(aProp);
if (aProp.Value <> Unassigned) then
l.Value := aProp.Value;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.CopyProperties(const aGen: TengShaderCodeGenerator);
var
l: TPropertyList;
p: TengShaderPartProperty;
begin
for l in fPropertyMap do
for p in l do
aGen.AddProperty(p, false);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.UpdateProperties;
begin
fPropertyMap.Clear;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderCodeGenerator.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
begin
result := inherited ParseIntern(aArgs, aParams);
UpdateProperties;
end;

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


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderCodeGenerator.Destroy; destructor TengShaderCodeGenerator.Destroy;
begin begin
FreeAndNil(fProperties);
FreeAndNil(fPropertyMap);
inherited Destroy; inherited Destroy;
end; end;




+ 65
- 1
uengShaderFile.pas Просмотреть файл

@@ -33,10 +33,12 @@ type
function GetGenerator(const aName: String): TengShaderCodeGenerator; function GetGenerator(const aName: String): TengShaderCodeGenerator;
function GetGeneratorCount: Integer; function GetGeneratorCount: Integer;
function GetGeneratorNames(const aIndex: Integer): String; function GetGeneratorNames(const aIndex: Integer): String;
procedure UpdateClasses;
protected protected
function GetFilename: String; override; function GetFilename: String; override;
function GetFileReader: IengShaderFileReader; override; function GetFileReader: IengShaderFileReader; override;
function GetFileWriter: IengShaderFileWriter; override; function GetFileWriter: IengShaderFileWriter; override;
procedure UpdateProperties; override;
public public
procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil); procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil); procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
@@ -60,7 +62,7 @@ type
implementation implementation


uses uses
uengShaderPartInclude;
uengShaderPartInclude, uengShaderPartKeyValuePair;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderFile//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderFile////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -88,6 +90,40 @@ begin
else result := fClasses.Keys[aIndex-1]; else result := fClasses.Keys[aIndex-1];
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.UpdateClasses;

procedure AddClass(const aClass: TengShaderPartClass);
var
c: TengShaderPartClass;
s: String;
begin
c := fClasses[aClass.Name];
if Assigned(c) then begin
s := Format('use of duplicate identifier: %s (%s %d:%d)', [aClass.Name, aClass.Filename, aClass.Line + 1, aClass.Col]) + sLineBreak +
'previously declared here:' + sLineBreak +
Format(' %s %d:%d', [c.Filename, c.Line + 1, c.Col]) + sLineBreak;
LogMsg(llWarning, s);
fClasses[aClass.Name] := aClass;
end else
fClasses.Add(aClass.Name, aClass);
end;

var
sr: TengSearchResults;
p: TengShaderPart;
begin
sr := TengSearchResults.Create([TengShaderPartClass]);
try
Find([sfSearchChildren], sr);
fClasses.Clear;
for p in sr.GetReverseEnumerator do
AddClass(p as TengShaderPartClass);
finally
FreeAndNil(sr);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderFile.GetFilename: String; function TengShaderFile.GetFilename: String;
begin begin
@@ -110,6 +146,32 @@ begin
result := Parent.FileWriter; result := Parent.FileWriter;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.UpdateProperties;
var
sr: TengSearchResults;
p: TengShaderPart;
begin
inherited UpdateProperties;

sr := TengSearchResults.Create([TengShaderFile]);
try
Find(SEARCH_FLAG_FILE_PROPERTIES, sr);
for p in sr.GetReverseEnumerator 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
AddProperty(p as TengShaderPartProperty);
finally
FreeAndNil(sr);
end;
end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader); procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader);
@@ -135,6 +197,8 @@ begin
token := ParseText(args); token := ParseText(args);
if (token <> '') then with args do if (token <> '') then with args do
raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self); raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self);
if (self = Root) then
UpdateClasses;
finally finally
FreeAndNil(args); FreeAndNil(args);
end; end;


+ 2
- 2
uengShaderFileConstants.pas Просмотреть файл

@@ -35,13 +35,13 @@ const
TOKEN_LAYOUT = TOKEN_CHAR_IDENT + 'LAYOUT'; //{$META $LAYOUT '(line_strip, max_vertices = 6) out'} TOKEN_LAYOUT = TOKEN_CHAR_IDENT + 'LAYOUT'; //{$META $LAYOUT '(line_strip, max_vertices = 6) out'}


TOKEN_PROPERTY = TOKEN_CHAR_IDENT + 'PROPERTY'; //{$PROPERTY InvertRoughmap 'false'} TOKEN_PROPERTY = TOKEN_CHAR_IDENT + 'PROPERTY'; //{$PROPERTY InvertRoughmap 'false'}
TOKEN_DEFINE = TOKEN_CHAR_IDENT + 'DEFINE'; //{$DEFINE RENDER_FACE_FRONT '0'}
TOKEN_UNDEF = TOKEN_CHAR_IDENT + 'UNDEF'; //{$UNDEF RENDER_FACE_FRONT}
TOKEN_STATIC = TOKEN_CHAR_IDENT + 'STATIC'; //{$STATIC RENDER_FACE_FRONT '0'}
TOKEN_ECHO = TOKEN_CHAR_IDENT + 'ECHO'; //{$ECHO InvertRoughmap} TOKEN_ECHO = TOKEN_CHAR_IDENT + 'ECHO'; //{$ECHO InvertRoughmap}


TOKEN_VAR = TOKEN_CHAR_IDENT + 'VAR'; //{$VAR 'float' 'refractivity' '0.0'} TOKEN_VAR = TOKEN_CHAR_IDENT + 'VAR'; //{$VAR 'float' 'refractivity' '0.0'}
TOKEN_VARYING = TOKEN_CHAR_IDENT + 'VARYING'; //{$VARYING 'vec3' 'vVertex'} TOKEN_VARYING = TOKEN_CHAR_IDENT + 'VARYING'; //{$VARYING 'vec3' 'vVertex'}
TOKEN_UNIFORM = TOKEN_CHAR_IDENT + 'UNIFORM'; //{$UNIFORM 'sampler2D' 'uShadowMap'} TOKEN_UNIFORM = TOKEN_CHAR_IDENT + 'UNIFORM'; //{$UNIFORM 'sampler2D' 'uShadowMap'}
TOKEN_CONST = TOKEN_CHAR_IDENT + 'CONST'; //{$CONST 'int' 'test' '0'}


TOKEN_CALL = TOKEN_CHAR_IDENT + 'CALL'; //{$CALL CalcLight} TOKEN_CALL = TOKEN_CHAR_IDENT + 'CALL'; //{$CALL CalcLight}
TOKEN_PROC = TOKEN_CHAR_IDENT + 'PROC'; //{$PROC CalcLight} Code... {$END} TOKEN_PROC = TOKEN_CHAR_IDENT + 'PROC'; //{$PROC CalcLight} Code... {$END}


+ 2
- 28
uengShaderFileExpression.pas Просмотреть файл

@@ -521,15 +521,6 @@ end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type type
TkvpSearchResults = class(TengSearchResults)
private
fName: String;
protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; override;
public
constructor Create(const aName: String);
end;

TExpectedParam = (exVariable, exValue, exGroupBegin, exGroupEnd, exUnaryOperation, exBinaryOperation); TExpectedParam = (exVariable, exValue, exGroupBegin, exGroupEnd, exUnaryOperation, exBinaryOperation);
TExpectedParams = set of TExpectedParam; TExpectedParams = set of TExpectedParam;
TExpressionParser = class(TObject) TExpressionParser = class(TObject)
@@ -550,23 +541,6 @@ type
constructor Create(const aParent: TengShaderPart; const aParams: TengTokenParameterList; const aIndex: Integer); constructor Create(const aParent: TengShaderPart; const aParams: TengTokenParameterList; const aIndex: Integer);
end; end;


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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TkvpSearchResults.Create(const aName: String);
begin
inherited Create([TengShaderPartKeyValuePair]);
fName := aName;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TExpressionParser///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TExpressionParser/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -712,9 +686,9 @@ begin
end else if IsValidIdentifier(param.Name) then begin end else if IsValidIdentifier(param.Name) then begin
if not (exVariable in aExpected) then if not (exVariable in aExpected) then
RaiseEx('unexpected variable:', param); RaiseEx('unexpected variable:', param);
sr := TkvpSearchResults.Create(param.Name);
sr := TkvpSearchResults.Create(param.Name, true, true);
try try
fParent.Find([], sr);
fParent.Find(SEARCH_FLAG_CURRENT_SCOPE, sr);
tmp := ExtractSearchResult(fParent, param.Name, sr, param.Line, param.Col); tmp := ExtractSearchResult(fParent, param.Name, sr, param.Line, param.Col);
result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col); result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col);
finally finally


+ 37
- 3
uengShaderFileHelper.pas Просмотреть файл

@@ -12,11 +12,21 @@ function IsValidIdentifier(const aIdent: String): Boolean;
function CheckEndToken(const aArgs: TengParseArgs; const aShaderPart: TengShaderPart): String; function CheckEndToken(const aArgs: TengParseArgs; const aShaderPart: TengShaderPart): String;
function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; aLine: Integer = -1; aCol: Integer = -1; aFilename: String = ''): TengShaderPart; function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList; aLine: Integer = -1; aCol: Integer = -1; aFilename: String = ''): TengShaderPart;


type
TkvpSearchResults = class(TengSearchResults)
private
fName: String;
protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; override;
public
constructor Create(const aName: String; const aSearchDefines, aSearchProperties: Boolean);
end;

implementation implementation


uses uses
sysutils, sysutils,
uengShaderFileConstants, uengShaderFileTypes;
uengShaderFileConstants, uengShaderFileTypes, uengShaderPartKeyValuePair;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function IsValidIdentifier(const aIdent: String): Boolean; function IsValidIdentifier(const aIdent: String): Boolean;
@@ -61,8 +71,6 @@ var
i: Integer; i: Integer;
begin begin
result := nil; result := nil;
if (aList.Count <= 0) then
exit;
if Assigned(aSender) then begin if Assigned(aSender) then begin
if (aLine < 0) then if (aLine < 0) then
aLine := aSender.Line; aLine := aSender.Line;
@@ -71,6 +79,8 @@ begin
if (aFilename = '') then if (aFilename = '') then
aFilename := aSender.Filename; aFilename := aSender.Filename;
end; end;
if (aList.Count <= 0) then
raise EengUnknownIdentifier.Create(aIdent, aLine, aCol, aFilename, aSender);
result := aList[0]; result := aList[0];
if (aList.Count > 1) and Assigned(aSender) then begin if (aList.Count > 1) and Assigned(aSender) then begin
s := Format('use of duplicate identifier: %s (%s %d:%d)', [aIdent, aList[0].Filename, aList[0].Line + 1, aList[0].Col]) + sLineBreak + s := Format('use of duplicate identifier: %s (%s %d:%d)', [aIdent, aList[0].Filename, aList[0].Line + 1, aList[0].Col]) + sLineBreak +
@@ -84,5 +94,29 @@ begin
end; end;
end; end;


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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TkvpSearchResults.Create(const aName: String; const aSearchDefines, aSearchProperties: Boolean);
begin
if aSearchDefines and aSearchProperties then
inherited Create([TengShaderPartStatic, TengShaderPartProperty])
else if aSearchDefines then
inherited Create([TengShaderPartStatic])
else if aSearchProperties then
inherited Create([TengShaderPartProperty])
else
inherited Create([]);
fName := aName;
end;

end. end.



+ 36
- 26
uengShaderPart.pas Просмотреть файл

@@ -22,7 +22,6 @@ type
TengSearchFlag = ( TengSearchFlag = (
sfEvaluateIf, // evaluate if statements before search and process with suitable subtree sfEvaluateIf, // evaluate if statements before search and process with suitable subtree
sfSearchAllIf, // search in all if sub trees sfSearchAllIf, // search in all if sub trees
sfIncludeSelf, // add item to search results where search has started


sfSearchPrevOnly, // search in previous items only sfSearchPrevOnly, // search in previous items only
sfSearchInherited, // search in inherited sfSearchInherited, // search in inherited
@@ -53,14 +52,23 @@ type
const const
SEARCH_FLAG_CURRENT_SCOPE = [ SEARCH_FLAG_CURRENT_SCOPE = [
sfSearchPrevOnly, sfSearchPrevOnly,
sfSearchInherited, // search in inherited

sfSearchChildrenLazy, // set sfSearchChildren in next recursion level
sfChildrenOnlyScope, // do not leave current scope when searching for children
sfChildrenForceFile, // overwrite sfChildrenOnlyXXX flag when item is a file

sfSearchParents, // search in Parents
sfParentsOnlyFile // do not leave current file when searching in parents
sfSearchInherited,
sfSearchChildrenLazy,
sfChildrenOnlyScope,
sfChildrenForceFile,
sfSearchParents,
sfParentsOnlyFile
];
SEARCH_FLAG_CLASS_PROPERTIES = [
sfSearchAllIf,
sfSearchChildren,
sfChildrenOnlyGenerator,
sfChildrenForceFile
];
SEARCH_FLAG_FILE_PROPERTIES = [
sfSearchAllIf,
sfSearchChildren,
sfChildrenOnlyGenerator
]; ];


type type
@@ -290,24 +298,23 @@ function TengShaderPart.FindIntern(aFlags: TengSearchFlags; const aChild: TengSh
exit; exit;
result := result and result := result and
Assigned(aItem) and Assigned(aItem) and
(not (sfChildrenOnlyFile in aFlags) or not (self is TengShaderFile)) and
(not (sfChildrenOnlyClass in aFlags) or not (self is TengShaderPartClass)) and
(not (sfChildrenOnlyGenerator in aFlags) or not (self is TengShaderCodeGenerator)) and
(not (sfChildrenOnlyScope in aFlags) or not (self is TengShaderPartScope));
(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 result := result or
((sfChildrenForceFile in aFlags) and (self is TengShaderFile)) or
((sfChildrenForceClass in aFlags) and (self is TengShaderPartClass)) or
((sfChildrenForceGenerator in aFlags) and (self is TengShaderCodeGenerator)) or
((sfChildrenForceScope in aFlags) and (self is TengShaderPartScope));
((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; end;


function VisitParent(const aItem: TengShaderPart): Boolean;
function VisitParent: Boolean;
begin begin
result := (sfSearchParents in aFlags); result := (sfSearchParents in aFlags);
if not result then if not result then
exit; exit;
result := result and result := result and
Assigned(aItem) and
(not (sfParentsOnlyFile in aFlags) or not (self is TengShaderFile)) and (not (sfParentsOnlyFile in aFlags) or not (self is TengShaderFile)) and
(not (sfParentsOnlyClass in aFlags) or not (self is TengShaderPartClass)) and (not (sfParentsOnlyClass in aFlags) or not (self is TengShaderPartClass)) and
(not (sfParentsOnlyGenerator in aFlags) or not (self is TengShaderCodeGenerator)) and (not (sfParentsOnlyGenerator in aFlags) or not (self is TengShaderCodeGenerator)) and
@@ -330,20 +337,23 @@ begin
b := b or (c = aChild); b := b or (c = aChild);
if (sfSearchPrevOnly in aFlags) and not b then if (sfSearchPrevOnly in aFlags) and not b then
continue; continue;
if (c <> aChild) and VisitChild(c) then
result := result and c.FindIntern(aFlags - [sfSearchParents] + [sfIncludeSelf], nil, aResults);
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 if not result then
exit; exit;
end; end;
end; end;


if (sfIncludeSelf in aFlags) then
result := result and aResults.Add(self);

if (sfSearchChildrenLazy in aFlags) then if (sfSearchChildrenLazy in aFlags) then
aFlags := aFlags + [sfSearchChildren] - [sfSearchChildrenLazy]; aFlags := aFlags + [sfSearchChildren] - [sfSearchChildrenLazy];
if VisitParent(Parent) then
result := result and Parent.FindIntern(aFlags + [sfIncludeSelf], self, aResults);
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; end;


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


+ 67
- 1
uengShaderPartClass.pas Просмотреть файл

@@ -16,21 +16,27 @@ uses


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartClass = class;
TengShaderPartClassList = specialize TutlSimpleList<TengShaderPartClass>;
TengShaderPartClass = class(TengShaderCodeGenerator) TengShaderPartClass = class(TengShaderCodeGenerator)
{ Code Loading & Storage } { Code Loading & Storage }
private { member } private { member }
fName: String; fName: String;
fExtends: TStringList; fExtends: TStringList;
fInherited: TengShaderPartClassList;
private { getter } private { getter }
function GetExtends: TStrings; function GetExtends: TStrings;
procedure UpdateInherited;
protected { virtual getter } protected { virtual getter }
function GetText: String; override; function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;
procedure UpdateProperties; override;


{ General } { General }
public public
property Name: String read fName; property Name: String read fName;
property Extends: TStrings read GetExtends; property Extends: TStrings read GetExtends;

constructor Create(const aParent: TengShaderPart); override; constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override; destructor Destroy; override;


@@ -44,7 +50,7 @@ type
implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartKeyValuePair;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartClass/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartClass///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -54,6 +60,41 @@ begin
result := fExtends; result := fExtends;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartClass.UpdateInherited;

procedure FilterResults(const aName: String; const aResults, aNewResults: TengShaderPartList);
var
p: TengShaderPart;
begin
aNewResults.Clear;
for p in aResults do
if ((p as TengShaderPartClass).Name = aName) then
aNewResults.Add(p);
end;

var
sr: TengSearchResults;
res: TengShaderPartList;
s: String;
begin
if (fExtends.Count <= 0) then
exit;
sr := TengSearchResults.Create([TengShaderPartClass]);
res := TengShaderPartList.Create(false);
try
fInherited.Clear;
Find(SEARCH_FLAG_CURRENT_SCOPE, sr);
for s in fExtends do begin
FilterResults(s, sr, res);
fInherited.Add(ExtractSearchResult(self, s, res) as TengShaderPartClass);
end;
finally
FreeAndNil(res);
FreeAndNil(sr);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartClass.GetText: String; function TengShaderPartClass.GetText: String;
var var
@@ -93,20 +134,45 @@ begin
for i := 3 to aParams.Count-1 do for i := 3 to aParams.Count-1 do
fExtends.Add(aParams[i].Name); fExtends.Add(aParams[i].Name);
end; end;
UpdateInherited;
result := inherited ParseIntern(aArgs, aParams); result := inherited ParseIntern(aArgs, aParams);
result := CheckEndToken(aArgs, self); result := CheckEndToken(aArgs, self);
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartClass.UpdateProperties;
var
sr: TengSearchResults;
p: TengShaderPart;
c: TengShaderPartClass;
begin
inherited UpdateProperties;

for c in fInherited do
c.CopyProperties(self);

sr := TengSearchResults.Create([TengShaderPartProperty]);
try
Find(SEARCH_FLAG_CLASS_PROPERTIES, sr);
for p in sr.GetReverseEnumerator do
AddProperty(p as TengShaderPartProperty);
finally
FreeAndNil(sr);
end;
end;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartClass.Create(const aParent: TengShaderPart); constructor TengShaderPartClass.Create(const aParent: TengShaderPart);
begin begin
inherited Create(aParent); inherited Create(aParent);
fExtends := TStringList.Create; fExtends := TStringList.Create;
fInherited := TengShaderPartClassList.Create(false);
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TengShaderPartClass.Destroy; destructor TengShaderPartClass.Destroy;
begin begin
FreeAndNil(fInherited);
FreeAndNil(fExtends); FreeAndNil(fExtends);
inherited Destroy; inherited Destroy;
end; end;


+ 3
- 2
uengShaderPartCntr.pas Просмотреть файл

@@ -36,10 +36,11 @@ uses
uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment; uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment;


const const
TOKEN_CLASSES: array[0..20] of CengShaderCodePart = (
TOKEN_CLASSES: array[0..21] of CengShaderCodePart = (
TengShaderPartCall, TengShaderPartCall,
TengShaderPartClass, TengShaderPartClass,
TengShaderPartDefine,
TengShaderPartConst,
TengShaderPartStatic,
TengShaderPartLineBreak, TengShaderPartLineBreak,
TengShaderPartCommandEnd, TengShaderPartCommandEnd,
TengShaderPartComment, TengShaderPartComment,


+ 5
- 5
uengShaderPartIf.pas Просмотреть файл

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


uses uses
Classes, SysUtils, Classes, SysUtils,
uengShaderPart, uengShaderPartCntr, uengShaderFileExpression, uengShaderFileParser;
uengShaderPart, uengShaderPartScope, uengShaderFileExpression, uengShaderFileParser;


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -49,7 +49,7 @@ type
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartElse = class(TengShaderPartCntr)
TengShaderPartElse = class(TengShaderPartScope)
{ Code Loading & Storage } { Code Loading & Storage }
protected protected
function GetText: String; override; function GetText: String; override;
@@ -132,7 +132,7 @@ begin


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


fIfPart := TengShaderPartCntr.Create(self);
fIfPart := TengShaderPartScope.Create(self);
result := fIfPart.ParseText(aArgs); result := fIfPart.ParseText(aArgs);
result := HandleToken(result, aArgs); result := HandleToken(result, aArgs);
end; end;
@@ -150,8 +150,8 @@ begin
fElsePart.Find(aFlags, aResults); fElsePart.Find(aFlags, aResults);
end; end;
end; end;
if not (sfSearchAllIf in aFlags) then
exclude(aFlags, sfSearchChildren);
if not (sfSearchAllIf in aFlags) and (sfSearchChildren in aFlags) then
aFlags := aFlags - [sfSearchChildren] + [sfSearchChildrenLazy];
result := result and inherited FindIntern(aFlags, aChild, aResults); result := result and inherited FindIntern(aFlags, aChild, aResults);
end; end;




+ 15
- 13
uengShaderPartKeyValuePair.pas Просмотреть файл

@@ -7,15 +7,11 @@ interface


uses uses
Classes, SysUtils, variants, Classes, SysUtils, variants,
uengShaderPart, uengShaderFileParser

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


type type
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartStatic = class;
TengShaderPartKeyValuePair = class(TengShaderCodePart) TengShaderPartKeyValuePair = class(TengShaderCodePart)
{ Code Loading & Storage } { Code Loading & Storage }
private private
@@ -39,10 +35,9 @@ type
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
end; end;
TengShaderPartPropertyMap = specialize TutlMap<string, TengShaderPartProperty>;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartDefine = class(TengShaderPartKeyValuePair)
TengShaderPartStatic = class(TengShaderPartKeyValuePair)
{ Class Methods } { Class Methods }
public public
class function GetTokenName: String; override; class function GetTokenName: String; override;
@@ -68,6 +63,8 @@ end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartKeyValuePair.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; function TengShaderPartKeyValuePair.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String;
var
sr: TengSearchResults;
begin begin
if (aParams[0].Name <> GetTokenName) then with aParams[0] do if (aParams[0].Name <> GetTokenName) then with aParams[0] do
raise EengInvalidToken.Create(ClassName, GetTokenName, Line, Col, Filename, self); raise EengInvalidToken.Create(ClassName, GetTokenName, Line, Col, Filename, self);
@@ -83,9 +80,14 @@ begin
fValue := aParams[2].Name; fValue := aParams[2].Name;
fValueName := ''; fValueName := '';
end else begin end else begin
// TODO resolve name and set value
fValue := Unassigned;
fValueName := aParams[2].Name; fValueName := aParams[2].Name;
sr := TkvpSearchResults.Create(fValueName, true, false);
try
Find(SEARCH_FLAG_CURRENT_SCOPE, sr);
fValue := (ExtractSearchResult(self, fValueName, sr) as TengShaderPartStatic).Value;
finally
FreeAndNil(sr);
end;
end end
else begin else begin
fValue := Unassigned; fValue := Unassigned;
@@ -102,11 +104,11 @@ begin
end; end;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartDefine//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartStatic//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartDefine.GetTokenName: String;
class function TengShaderPartStatic.GetTokenName: String;
begin begin
result := TOKEN_DEFINE;
result := TOKEN_STATIC;
end; end;


end. end.


+ 51
- 1
uengShaderPartParameter.pas Просмотреть файл

@@ -58,13 +58,31 @@ type
class function GetTokenName: String; override; class function GetTokenName: String; override;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderPartConst = class(TengShaderPartParameter)
{ Code Loading & Storage }
private
fValue: String;
protected
function GetText: String; override;
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;

{ General }
public
property Value: String read fValue;

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

implementation implementation


uses uses
uengShaderFileConstants, uengShaderFileTypes; uengShaderFileConstants, uengShaderFileTypes;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartParameter///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartParameter.GetText: String; function TengShaderPartParameter.GetText: String;
begin begin
@@ -139,5 +157,37 @@ begin
result := TOKEN_UNIFORM; result := TOKEN_UNIFORM;
end; end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartConst///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartConst.GetText: String;
begin
result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' +
TOKEN_CHAR_QUOTE + fType + TOKEN_CHAR_QUOTE + ' ' +
TOKEN_CHAR_QUOTE + fName + TOKEN_CHAR_QUOTE + ' ' +
TOKEN_CHAR_QUOTE + fValue + TOKEN_CHAR_QUOTE +
TOKEN_CHAR_END;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartConst.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 <> 4) then
raise EengInvalidParamterCount.Create(GetTokenName, 4, self);

result := '';
fType := aParams[1].Name;
fName := aParams[2].Name;
fValue := aParams[3].Name
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TengShaderPartConst.GetTokenName: String;
begin
result := TOKEN_CONST;
end;

end. end.



Загрузка…
Отмена
Сохранить