|
- unit uengShaderPart;
-
- {$mode objfpc}{$H+}
- {$I uengShaderFile.inc}
-
- interface
-
- uses
- Classes, SysUtils,
-
- uengShaderFileParser, uengShaderFileTypes
-
- {$IFDEF USE_BITSPACE_UTILS}
- , uutlGenerics
- {$ELSE}
- , fgl
- {$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
- 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
-
- 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
- );
- TengSearchFlags = set of TengSearchFlag;
-
- TengShaderPart = class;
- CengShaderPart = class of TengShaderPart;
- TengShaderPartList = specialize TutlSimpleList<TengShaderPart>;
- TengShaderPart = class(TIntfObjNoRefCount)
- { Nested Types }
- public type
- TEnumerator = class(TObject)
- private
- fOwner: TengShaderPart;
- fPosition: Integer;
- fReverse: Boolean;
- function GetCurrent: TengShaderPart;
- public
- property Current: TengShaderPart read GetCurrent;
- function GetEnumerator: TEnumerator;
- function MoveNext: Boolean;
- 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 }
- fParent: TengShaderPart;
- fLine: Integer;
- fCol: Integer;
- fRoot: TengShaderPart;
- protected { virtual getter }
- function GetCount: Integer; virtual;
- function GetChild(const aIndex: Integer): TengShaderPart; virtual;
- function GetText: String; virtual;
- function GetFilename: String; virtual;
- function GetFileReader: IengShaderFileReader; virtual;
- function GetFileWriter: IengShaderFileWriter; virtual;
-
- { General }
- protected
- procedure UpdateCache; virtual;
- function FindIntern(aFlags: TengSearchFlags; const aChild: TengShaderPart; const aResults: TSearchResults): Boolean; virtual;
- public { general methods }
- property Root: TengShaderPart read fRoot;
- property Parent: TengShaderPart read fParent;
- property Line: Integer read fLine;
- property Col: Integer read fCol;
- property Filename: String read GetFilename;
- property Text: String read GetText;
- property Count: Integer read GetCount;
-
- property FileReader: IengShaderFileReader read GetFileReader;
- property FileWriter: IengShaderFileWriter read GetFileWriter;
-
- property Children[const aIndex: Integer]: TengShaderPart read GetChild; default;
-
- function HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean = false): Boolean;
- function GetParent(const aType: CengShaderPart; out aPart): Boolean;
- function GetParent(const aType: CengShaderPart): TengShaderPart;
-
- procedure Find(const aFlags: TengSearchFlags; const aResults: TSearchResults);
-
- function GetEnumerator: TEnumerator;
- function GetReverseEnumerator: TEnumerator;
-
- constructor Create(const aParent: TengShaderPart); virtual;
-
- { Class Methods }
- public
- class function GetTokenName: String; virtual;
- class function CheckToken(const aToken: String): Boolean; virtual;
- 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, uengShaderFile, uengShaderFileConstants;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TengShaderPart.TEnumerator////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.TEnumerator.GetCurrent: TengShaderPart;
- begin
- result := fOwner[fPosition];
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.TEnumerator.GetEnumerator: TEnumerator;
- begin
- result := self;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.TEnumerator.MoveNext: Boolean;
- begin
- if not fReverse
- then inc(fPosition)
- else dec(fPosition);
- result := (0 <= fPosition) and (fPosition < fOwner.Count);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- constructor TengShaderPart.TEnumerator.Create(const aOwner: TengShaderPart; const aReverse: Boolean);
- begin
- inherited Create;
- fOwner := aOwner;
- fReverse := aReverse;
- if not fReverse
- then fPosition := -1
- else fPosition := aOwner.Count;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TengShaderPart.TSearchResults/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.TSearchResults.CheckObj(const aPart: TengShaderPart; var aContinue: Boolean): Boolean;
- var
- c: CengShaderPart;
- 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 TengShaderPart.TSearchResults.Add(const aPart: TengShaderPart): Boolean;
- begin
- result := true;
- if result and CheckObj(aPart, result) then
- inherited Add(aPart);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- constructor TengShaderPart.TSearchResults.Create(const aTypes: array of CengShaderPart);
- var
- i: Integer;
- begin
- inherited Create(false);
- fFirstOnly := false;
- SetLength(fTypes, Length(aTypes));
- for i := Low(fTypes) to High(fTypes) do
- fTypes[i] := aTypes[i];
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- //TengShaderPart////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetCount: Integer;
- begin
- result := 0;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.{%H-}GetChild(const aIndex: Integer): TengShaderPart;
- begin
- EengShaderPartInternal.Create('this part does not have any children');
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetText: String;
- begin
- result := ''; //DUMMY
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetFilename: String;
- begin
- if Assigned(fParent)
- then result := fParent.Filename
- else result := UNKNOWN_FILENAME;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetFileReader: IengShaderFileReader;
- begin
- if Assigned(fParent)
- then result := fParent.GetFileReader
- else result := nil;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetFileWriter: IengShaderFileWriter;
- begin
- if Assigned(fParent)
- then result := fParent.GetFileWriter
- else result := nil;
- 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: TSearchResults): Boolean;
- 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) 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 not result then
- exit;
- end;
- end;
-
- 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);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.HasParent(const aType: CengShaderPart; const aIncludeSelf: Boolean): Boolean;
- var
- p: TengShaderPart;
- begin
- result := (aIncludeSelf and (self is aType)) or GetParent(aType, p);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetParent(const aType: CengShaderPart; out aPart): Boolean;
- begin
- result := true;
- if (fParent is aType) then
- TengShaderPart(aPart) := fParent
- else if Assigned(fParent) then
- result := fParent.GetParent(aType, aPart)
- else
- result := false;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetParent(const aType: CengShaderPart): TengShaderPart;
- begin
- if not GetParent(aType, result) then
- raise EengShaderPartInternal.Create(GetTokenName + ' ha sno parent of type ' + aType.GetTokenName, self);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- procedure TengShaderPart.Find(const aFlags: TengSearchFlags; const aResults: TSearchResults);
- begin
- FindIntern(aFlags, nil, aResults);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetEnumerator: TEnumerator;
- begin
- result := TEnumerator.Create(self);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- function TengShaderPart.GetReverseEnumerator: TEnumerator;
- begin
- result := TEnumerator.Create(self, true);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- constructor TengShaderPart.Create(const aParent: TengShaderPart);
- begin
- inherited Create;
- fParent := aParent;
- if Assigned(fParent)
- then fRoot := fParent.Root
- else fRoot := nil;
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class function TengShaderPart.GetTokenName: String;
- begin
- result := ''; // DUMMY
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class function TengShaderPart.CheckToken(const aToken: String): Boolean;
- begin
- result := (aToken = GetTokenName);
- end;
-
- ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- class procedure TengShaderPart.Validate(const aArgs: TengParseArgs; const aParent: TengShaderPart);
- 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.
|