Bergmann89 преди 11 години
родител
ревизия
5047d72d2a
променени са 11 файла, в които са добавени 316 реда и са изтрити 202 реда
  1. +3
    -20
      uengShaderCodeGenerator.pas
  2. +1
    -1
      uengShaderFile.inc
  3. +21
    -38
      uengShaderFile.pas
  4. +1
    -2
      uengShaderFileConstants.pas
  5. +107
    -37
      uengShaderFileExpression.pas
  6. +32
    -0
      uengShaderFileHelper.pas
  7. +8
    -8
      uengShaderFileTypes.pas
  8. +137
    -53
      uengShaderPart.pas
  9. +1
    -39
      uengShaderPartClass.pas
  10. +3
    -2
      uengShaderPartIf.pas
  11. +2
    -2
      uengShaderPartKeyValuePair.pas

+ 3
- 20
uengShaderCodeGenerator.pas Целия файл

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -15,10 +15,6 @@ type
{ General }
private
fProperties: TengShaderPartPropertyMap;
protected
fInherited: TengShaderPartList;
procedure UpdateInherited; virtual;
procedure UpdateCache; override;
public
constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override;
@@ -28,30 +24,17 @@ implementation

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderCodeGenerator///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.UpdateInherited;
begin
// DUMMY
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderCodeGenerator.UpdateCache;
begin
inherited UpdateCache;
UpdateInherited;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderCodeGenerator.Create(const aParent: TengShaderPart);
begin
inherited Create(aParent);
fInherited := TengShaderPartList.Create(false);
fProperties := TengShaderPartPropertyMap.Create(false);
end;

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



+ 1
- 1
uengShaderFile.inc Целия файл

@@ -1,3 +1,3 @@
{$DEFINE EXPRESSION_ADD_BRACKET} // add brackets to expressions
{.$DEFINE EXPRESSION_ADD_BRACKET} // add brackets to expressions
{$DEFINE USE_BITSPACE_UTILS} // use bitSpace Utils
{$DEFINE DEBUG} // enable debug output

+ 21
- 38
uengShaderFile.pas Целия файл

@@ -21,6 +21,7 @@ uses

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengShaderFileLogEvent = procedure(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String) of object;
TengShaderFile = class(TengShaderCodeGenerator)
{ Code Loading & Storage }
private
@@ -36,19 +37,21 @@ type
function GetFilename: String; override;
function GetFileReader: IengShaderFileReader; override;
function GetFileWriter: IengShaderFileWriter; override;
public
procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);

{ General }
private
procedure UpdateClasses;
fOnLog: TengShaderFileLogEvent;
protected
procedure UpdateCache; override;
procedure LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String); override;
public
property Generator [const aName: String]: TengShaderCodeGenerator read GetGenerator;
property GeneratorNames[const aIndex: Integer]: String read GetGeneratorNames;
property GeneratorCount: Integer read GetGeneratorCount;
property OnLog: TengShaderFileLogEvent read fOnLog write fOnLog;

procedure LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader = nil);
procedure SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter = nil);
procedure Clear; override;
constructor Create(const aParent: TengShaderPart); override;
destructor Destroy; override;
@@ -107,35 +110,6 @@ begin
result := Parent.FileWriter;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.UpdateClasses;
var
sr: TengShaderPart.TSearchResults;
p: TengShaderPart;
new, old: TengShaderPartClass;
begin
sr := TengShaderPart.TSearchResults.Create([TengShaderPartClass]);
try
fClasses.Clear;
Find([sfSearchChildren], sr);
for p in sr do begin
new := (p as TengShaderPartClass);
old := fClasses[new.Name];
if Assigned(old) then
raise EengDuplicateIdentifier.Create(new.Name, new, old, self);
fClasses.Add(new.Name, new);
end;
finally
FreeAndNil(sr);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.UpdateCache;
begin
inherited UpdateCache;
UpdateClasses;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LoadFromFile(const aFilename: String; const aFileReader: IengShaderFileReader);
@@ -161,8 +135,6 @@ begin
token := ParseText(args);
if (token <> '') then with args do
raise EengShaderPart.Create('unknown token ''' + token + '''', Line, Col, Filename, self);
if (Root = self) then
UpdateCache;
finally
FreeAndNil(args);
end;
@@ -174,7 +146,7 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.SaveToFile(const aFilename: String; const aFileWriter: IengShaderFileWriter);
var
sr: TengShaderPart.TSearchResults;
sr: TengSearchResults;
i: Integer;
sl: TStringList;
ms: TMemoryStream;
@@ -185,11 +157,11 @@ begin
if not Assigned(fFileWriter) then
fFileWriter := TengShaderFileWriter.Create;

sr := TengShaderPart.TSearchResults.Create([TengShaderPartInclude]);
sr := TengSearchResults.Create([TengShaderPartInclude]);
sl := TStringList.Create;
ms := TMemoryStream.Create;
try
Find([sfSearchChildren, sfChildrenFileOnly], sr);
Find([sfSearchChildren, sfChildrenOnlyFile], sr);
for i := 0 to sr.Count-1 do
(sr[i] as TengShaderPartInclude).SaveToFile(aFilename, aFileWriter);
sl.Text := Text;
@@ -204,6 +176,17 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
var
tmp: TengShaderFileLogEvent;
begin
inherited LogMsgIntern(aSender, aLogLevel, aMsg);
tmp := fOnLog;
if Assigned(tmp) then
tmp(aSender, aLogLevel, aMsg);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderFile.Clear;
begin


+ 1
- 2
uengShaderFileConstants.pas Целия файл

@@ -36,6 +36,7 @@ const

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_ECHO = TOKEN_CHAR_IDENT + 'ECHO'; //{$ECHO InvertRoughmap}

TOKEN_VAR = TOKEN_CHAR_IDENT + 'VAR'; //{$VAR 'float' 'refractivity' '0.0'}
@@ -61,8 +62,6 @@ const
TOKEN_OP_LOGICAL_OR = TOKEN_CHAR_IDENT + 'OR'; //{$IF test1 $OR test2}
TOKEN_OP_LOGICAL_AND = TOKEN_CHAR_IDENT + 'AND'; //{$IF test1 $AND test2}
TOKEN_OP_LOGICAL_XOR = TOKEN_CHAR_IDENT + 'XOR'; //{$IF test1 $XOR test2}
TOKEN_OP_DEFINED = TOKEN_CHAR_IDENT + 'DEFINED'; //{$IF $DEFINED test2}
TOKEN_OP_SET = TOKEN_CHAR_IDENT + 'SET'; //{$IF $SET vVertex}
TOKEN_OP_ADD = '+'; //{$IF test1 + test2}
TOKEN_OP_SUBTRACT = '-'; //{$IF test1 - test2}
TOKEN_OP_MULTIPLY = '*'; //{$IF test1 * test2}


+ 107
- 37
uengShaderFileExpression.pas Целия файл

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

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

type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengExpressionItem = class(TengShaderPart)
public
function GetValue: Variant; virtual;
constructor Create(const aLine, aCol: Integer);
constructor Create(const aLine, aCol: Integer); reintroduce;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -34,19 +34,24 @@ type
TengExpressionVariable = class(TengExpressionItem)
private
fName: String;
fPart: TengShaderPartKeyValuePair;
public
property Name: String read fName;
property Name: String read fName;
property Part: TengShaderPartKeyValuePair read fPart;

function GetText: String; override;
function GetValue: Variant; override;

constructor Create(const aName: String; const aLine, aCol: Integer);
constructor Create(const aName: String; const aPart: TengShaderPartKeyValuePair; const aLine, aCol: Integer);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengExpressionGroup = class(TengExpressionItem)
private
fChild: TengExpressionItem;
protected
function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override;
public
property Child: TengExpressionItem read fChild;

@@ -70,9 +75,7 @@ type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TengExpressionUnaryOperator = (
opBinaryNot,
opLogicalNot,
opDefined,
opSet
opLogicalNot
);
TengExpressionUnaryOperation = class(TengExpressionOperation)
private
@@ -80,6 +83,8 @@ type
fUnaryOp: TengExpressionUnaryOperator;
protected
function GetWeight: Integer; override;
function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override;
public
property Child: TengExpressionItem read fChild;
property UnaryOp: TengExpressionUnaryOperator read fUnaryOp;
@@ -107,6 +112,8 @@ type
fBinaryOp: TengExpressionBinaryOperator;
protected
function GetWeight: Integer; override;
function GetCount: Integer; override;
function GetChild(const aIndex: Integer): TengShaderPart; override;
public
property First: TengExpressionItem read fFirst write fFirst;
property Second: TengExpressionItem read fSecond write fSecond;
@@ -126,20 +133,12 @@ type
implementation

uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper
{$IFDEF USE_BITSPACE_UTILS}
, uutlGenerics
{$ELSE}
, fgl
{$ENDIF}
;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;

const
EXPRESSION_UNARY_OPERATIONS: array[TengExpressionUnaryOperator] of String = (
TOKEN_OP_BINARY_NOT, //opBinaryNot
TOKEN_OP_LOGICAL_NOT, //opLogicalNot
TOKEN_OP_DEFINED, //opDefined
TOKEN_OP_SET //opSet
TOKEN_OP_LOGICAL_NOT //opLogicalNot
);
EXPRESSION_BINARY_OPERATIONS: array[TengExpressionBinaryOperator] of String = (
TOKEN_OP_BINARY_OR, //opBinaryOr
@@ -165,9 +164,7 @@ const

UNARY_OPERATION_WEIGHTS: array[TengExpressionUnaryOperator] of Integer = (
00, //opBinaryNot
00, //opLogicalNot
00, //opDefined
00 //opSet
00 //opLogicalNot
);
BINARY_OPERATION_WEIGHTS: array[TengExpressionBinaryOperator] of Integer = (
01, //opBinaryOr
@@ -243,14 +240,29 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengExpressionVariable.Create(const aName: String; const aLine, aCol: Integer);
constructor TengExpressionVariable.Create(const aName: String; const aPart: TengShaderPartKeyValuePair; const aLine, aCol: Integer);
begin
inherited Create(aLine, aCol);
fName := aName;
fPart := aPart;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///TengExpressionGroup//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengExpressionGroup///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionGroup.GetCount: Integer;
begin
result := 1;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionGroup.GetChild(const aIndex: Integer): TengShaderPart;
begin
if (aIndex >= 0) and (aIndex < 1)
then result := fChild
else raise EengOutOfRange.Create(0, 0, aIndex, self);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionGroup.GetText: String;
begin
@@ -309,6 +321,20 @@ begin
result := UNARY_OPERATION_WEIGHTS[fUnaryOp];
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionUnaryOperation.GetCount: Integer;
begin
result := 1;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionUnaryOperation.GetChild(const aIndex: Integer): TengShaderPart;
begin
if (aIndex >= 0) and (aIndex < 1)
then result := fChild
else raise EengOutOfRange.Create(0, 0, aIndex, self);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionUnaryOperation.GetText: String;
begin
@@ -339,15 +365,6 @@ begin
v := fChild.GetValue;
result := not Boolean(v);
end;

opDefined: begin
// TODO
end;

opSet: begin
// TODO
end;

else
result := inherited GetValue;
end;
@@ -397,6 +414,23 @@ begin
result := BINARY_OPERATION_WEIGHTS[fBinaryOp];
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionBinaryOperation.GetCount: Integer;
begin
result := 2;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionBinaryOperation.GetChild(const aIndex: Integer): TengShaderPart;
begin
if (aIndex < 0) and (aIndex >= 2) then
raise EengOutOfRange.Create(0, 1, aIndex, self);
case aIndex of
0: result := fFirst;
1: result := fSecond;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengExpressionBinaryOperation.GetText: String;
begin
@@ -487,6 +521,15 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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);
TExpectedParams = set of TExpectedParam;
TExpressionParser = class(TObject)
@@ -495,27 +538,45 @@ type
fParamPos: Integer;
fParams: TengTokenParameterList;
private
function NextParam(var aParam: TengTokenParameter): Boolean;
function NextParam(out aParam: TengTokenParameter): Boolean;
function IsUnaryOperation(const aParam: String; out aOperator: TengExpressionUnaryOperator): Boolean;
function IsBinaryOperation(const aParam: String; out aOperator: TengExpressionBinaryOperator): Boolean;
procedure RaiseEx(const aMsg: String; const aParam: TengTokenParameter; aName: String = '');
function Move(var aItem: TengExpressionItem): TengExpressionItem;
function Merge(aOld, aNew: TengExpressionItem): TengExpressionItem;
function GetExpr(const aExpected: TExpectedParams): TengExpressionItem;
private
public
function GetGroup: TengExpressionItem;
constructor Create(const aParent: TengShaderPart; const aParams: TengTokenParameterList; const aIndex: Integer);
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/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TExpressionParser.NextParam(var aParam: TengTokenParameter): Boolean;
function TExpressionParser.NextParam(out aParam: TengTokenParameter): Boolean;
begin
inc(fParamPos);
result := (fParamPos < fParams.Count);
if result then
aParam := fParams[fParamPos];
if result
then aParam := fParams[fParamPos]
else FillByte(aParam, SizeOf(aParam), 0);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -607,6 +668,8 @@ var
bOp: TengExpressionBinaryOperator;
item: TengExpressionItem;
param: TengTokenParameter;
sr: TkvpSearchResults;
tmp: TengShaderPart;
begin
item := nil;
result := nil;
@@ -649,7 +712,14 @@ begin
end else if IsValidIdentifier(param.Name) then begin
if not (exVariable in aExpected) then
RaiseEx('unexpected variable:', param);
result := TengExpressionVariable.Create(param.Name, param.Line, param.Col);
sr := TkvpSearchResults.Create(param.Name);
try
fParent.Find([], sr);
tmp := ExtractSearchResult(fParent, param.Name, sr, param.Line, param.Col);
result := TengExpressionVariable.Create(param.Name, (tmp as TengShaderPartKeyValuePair), param.Line, param.Col);
finally
FreeAndNil(sr);
end;

// Unknown
end else


+ 32
- 0
uengShaderFileHelper.pas Целия файл

@@ -10,6 +10,7 @@ uses

function IsValidIdentifier(const aIdent: String): Boolean;
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;

implementation

@@ -52,5 +53,36 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ExtractSearchResult(const aSender: TengShaderPart; const aIdent: String; const aList: TengShaderPartList;
aLine: Integer; aCol: Integer; aFilename: String): TengShaderPart;
var
s: String;
i: Integer;
begin
result := nil;
if (aList.Count <= 0) then
exit;
if Assigned(aSender) then begin
if (aLine < 0) then
aLine := aSender.Line;
if (aCol < 0) then
aCol := aSender.Col;
if (aFilename = '') then
aFilename := aSender.Filename;
end;
result := aList[0];
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 +
'previously declared here:' + sLineBreak;
i := 1;
while (i < aList.Count) do begin
s := s + Format(' %s %d:%d', [aList[i].Filename, aList[i].Line + 1, aList[i].Col]) + sLineBreak;
inc(i);
end;
aSender.LogMsg(llWarning, s);
end;
end;

end.


+ 8
- 8
uengShaderFileTypes.pas Целия файл

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

TengShaderPartLogLevel = (
llInfo,
llWarning,
llError
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Exceptions////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -174,18 +180,12 @@ procedure EengShaderPart.PrintTrace(const aLines: TStrings);
else result := result + ' (' + aPart.ClassName + ')';
end;

var
p: TengShaderPart;
begin
if not Assigned(Sender) or not
(Sender is TengShaderPart) then
exit;
p := (Sender as TengShaderPart);
aLines.Text := Message;
while Assigned(p) do begin
aLines.Add(Format(' %s (%d:%d): %s', [p.Filename, p.Line+1, p.Col, GetName(p)]));
p := p.Parent;
end;
aLines.Add(Message);
(Sender as TengShaderPart).PrintTrace(' ', aLines);
end;

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


+ 137
- 53
uengShaderPart.pas Целия файл

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

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

sfSearchChildren, // search in children
sfSearchChildrenLazy, // set sfSearchChildren in next recursion level
sfChildrenFileOnly, // do not leave current file when searching for children
sfChildrenGeneratorOnly, // do not leave current generator when searching for children
sfChildrenScopeOnly, // do not leave current scope when searching for children
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
sfParentsFileOnly, // do not leave current file when searching in parents
sfParentsGeneratorOnly, // do not leave current generator when searching in parents
sfParentsScopeOnly // do not leave current scope when searching 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, // 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
];

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

TengSearchResults = class(specialize TutlList<TengShaderPart>)
private
fFirstOnly: Boolean;
fIgnore: TengShaderPart;
fTypes: array of CengShaderPart;
protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; 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);
end;

TengShaderPart = class(TIntfObjNoRefCount)
{ Nested Types }
public type
@@ -58,26 +99,12 @@ type
constructor Create(const aOwner: TengShaderPart; const aReverse: Boolean = false);
end;

TSearchResults = class(specialize TutlList<TengShaderPart>)
private
fFirstOnly: Boolean;
fIgnore: TengShaderPart;
fTypes: array of CengShaderPart;
protected
function CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean; 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);
end;

{ Code Loading & Storage }
protected { members }
fRoot: TengShaderPart;
fParent: TengShaderPart;
fLine: Integer;
fCol: Integer;
fRoot: TengShaderPart;
protected { virtual getter }
function GetCount: Integer; virtual;
function GetChild(const aIndex: Integer): TengShaderPart; virtual;
@@ -88,8 +115,8 @@ type

{ General }
protected
procedure UpdateCache; virtual;
function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean; virtual;
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;
property Parent: TengShaderPart read fParent;
@@ -108,7 +135,9 @@ type
function GetParent(const aType: CengShaderPart; out aPart): Boolean;
function GetParent(const aType: CengShaderPart): TengShaderPart;

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

function GetEnumerator: TEnumerator;
function GetReverseEnumerator: TEnumerator;
@@ -134,7 +163,7 @@ type
implementation

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

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -171,9 +200,9 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPart.TSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.TSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean;
function TengSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean;
var
c: CengShaderPart;
begin
@@ -188,7 +217,7 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.TSearchResults.Add(const aPart: TengShaderPart): Boolean;
function TengSearchResults.Add(const aPart: TengShaderPart): Boolean;
begin
result := true;
if result and CheckObj(aPart, result) then
@@ -196,7 +225,7 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPart.TSearchResults.Create(const aTypes: array of CengShaderPart);
constructor TengSearchResults.Create(const aTypes: array of CengShaderPart);
var
i: Integer;
begin
@@ -252,16 +281,44 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.UpdateCache;
var
p: TengShaderPart;
begin
for p in self do
p.UpdateCache;
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 (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));
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));
end;

function VisitParent(const aItem: TengShaderPart): Boolean;
begin
result := (sfSearchParents in aFlags);
if not result then
exit;
result := result and
Assigned(aItem) 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;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPart.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean;
var
c: TengShaderPart;
b: Boolean;
@@ -273,28 +330,27 @@ begin
b := b or (c = aChild);
if (sfSearchPrevOnly in aFlags) and not b then
continue;
if (c <> aChild) and
(not (sfChildrenScopeOnly in aFlags) or not (c is TengShaderPartScope)) and
(not (sfChildrenGeneratorOnly in aFlags) or not (c is TengShaderCodeGenerator)) and
(not (sfChildrenFileOnly in aFlags) or not (c is TengShaderFile))
then
result := result and c.FindIntern(aFlags - [sfSearchParents], nil, aResults);
if (c <> aChild) and VisitChild(c) then
result := result and c.FindIntern(aFlags - [sfSearchParents] + [sfIncludeSelf], nil, aResults);
if not result then
exit;
end;
end;

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

if (sfSearchChildrenLazy in aFlags) then
aFlags := aFlags + [sfSearchChildren] - [sfSearchChildrenLazy];
if (sfSearchParents in aFlags) and
Assigned(Parent) and
(not (sfParentsScopeOnly in aFlags) or not (self is TengShaderPartScope)) and
(not (sfParentsGeneratorOnly in aFlags) or not (self is TengShaderCodeGenerator)) and
(not (sfParentsFileOnly in aFlags) or not (self is TengShaderFile))
then
result := result and Parent.FindIntern(aFlags, self, aResults);
if VisitParent(Parent) then
result := result and Parent.FindIntern(aFlags + [sfIncludeSelf], self, aResults);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.LogMsgIntern(const aSender: TengShaderPart; const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
begin
if Assigned(Parent) then
Parent.LogMsgIntern(aSender, aLogLevel, aMsg);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -309,6 +365,7 @@ end;
function TengShaderPart.GetParent(const aType: CengShaderPart; out aPart): Boolean;
begin
result := true;
TengShaderPart(aPart) := nil;
if (fParent is aType) then
TengShaderPart(aPart) := fParent
else if Assigned(fParent) then
@@ -325,11 +382,38 @@ begin
end;

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

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

function GetName(const aPart: TengShaderPart): String;
begin
result := aPart.GetTokenName;
if (result = '')
then result := aPart.ClassName
else result := result + ' (' + aPart.ClassName + ')';
end;

var
p: TengShaderPart;
begin
p := self;
while Assigned(p) do begin
aLines.Add(Format('%s%s (%d:%d): %s', [aPrefix, p.Filename, p.Line+1, p.Col, GetName(p)]));
p := p.Parent;
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPart.LogMsg(const aLogLevel: TengShaderPartLogLevel; const aMsg: String);
begin
LogMsgIntern(self, aLogLevel, aMsg);
end;

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


+ 1
- 39
uengShaderPartClass.pas Целия файл

@@ -28,8 +28,6 @@ type
function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override;

{ General }
protected
procedure UpdateInherited; override;
public
property Name: String read fName;
property Extends: TStrings read GetExtends;
@@ -46,7 +44,7 @@ type
implementation

uses
uengShaderFile, uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartIf;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartClass///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -99,36 +97,6 @@ begin
result := CheckEndToken(aArgs, self);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TengShaderPartClass.UpdateInherited;
var
sr: TengShaderPart.TSearchResults;
i: Integer;
s: String;
begin
inherited UpdateInherited;
fInherited.Clear;
sr := TengShaderPart.TSearchResults.Create([TengShaderPartClass]);
try
sr.Ignore := self;
Find([sfSearchChildrenLazy, sfSearchParents, sfParentsFileOnly, sfSearchPrevOnly], sr);
for s in fExtends do begin
i := 0;
while (i >= 0) and (i < sr.Count) do begin
if ((sr[i] as TengShaderPartClass).Name = s) then begin
fInherited.Add(sr[i]);
i := -1;
end;
inc(i);
end;
if (i > 0) or (sr.Count = 0) then
raise EengUnknownIdentifier.Create(s, self);
end;
finally
FreeAndNil(sr);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TengShaderPartClass.Create(const aParent: TengShaderPart);
begin
@@ -160,12 +128,6 @@ class procedure TengShaderPartClass.Validate(const aArgs: TengParseArgs; const a

begin
inherited Validate(aArgs, aParent);
if aParent.HasParent(TengShaderPartElIf, true) then
RaiseEx(TengShaderPartElIf.GetTokenName);
if aParent.HasParent(TengShaderPartElse, true) then
RaiseEx(TengShaderPartElse.GetTokenName);
if aParent.HasParent(TengShaderPartIf, true) then
RaiseEx(TengShaderPartIf.GetTokenName);
if aParent.HasParent(TengShaderPartClass, true) then
RaiseEx(TengShaderPartClass.GetTokenName);
end;


+ 3
- 2
uengShaderPartIf.pas Целия файл

@@ -27,8 +27,9 @@ type

{ General }
protected
function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean; override;
function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean; override;
public
property Expression: TengExpressionItem read fExpression;
destructor Destroy; override;

{ Class Methods }
@@ -137,7 +138,7 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TengShaderPartIf.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean;
function TengShaderPartIf.FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TengSearchResults): Boolean;
begin
result := true;
if (sfEvaluateIf in aFlags) and (sfSearchChildren in aFlags) then begin


+ 2
- 2
uengShaderPartKeyValuePair.pas Целия файл

@@ -51,7 +51,7 @@ type
implementation

uses
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper, uengShaderPartIf;
uengShaderFileConstants, uengShaderFileTypes, uengShaderFileHelper;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TengShaderPartKeyValuePair////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -62,7 +62,7 @@ begin
if (fValueName <> '') then
result := result + ' ' + fValueName
else if (fValue <> Unassigned) then
result := result + TOKEN_CHAR_QUOTE + String(fValue) + TOKEN_CHAR_QUOTE;
result := result + ' ' + TOKEN_CHAR_QUOTE + String(fValue) + TOKEN_CHAR_QUOTE;
result := result + TOKEN_CHAR_END;
end;



Зареждане…
Отказ
Запис