unit uengShaderPartCntr; {$mode objfpc}{$H+} {$I uengShaderFile.inc} interface uses Classes, SysUtils, uengShaderPart, uengShaderCodePart, uengShaderFileParser, uengShaderGeneratorArgs; type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengShaderPartCntr = class(TengShaderCodePart) { Code Loading & Storage } private fChildren: TengShaderCodePartList; function HandleToken(const aToken: String; const aArgs: TengParseArgs): String; protected { virtual getter } function GetCount: Integer; override; function GetChild(const aIndex: Integer): TengShaderPart; override; function GetText: String; override; function ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; override; public procedure AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean = false); { Code Generation } public procedure GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); override; { General } public procedure Clear; virtual; constructor Create(const aParent: TengShaderPart); override; destructor Destroy; override; end; implementation uses uengShaderPartKeyValuePair, uengShaderPartClass, uengShaderPartMessage, uengShaderPartMeta, uengShaderPartCall, uengShaderPartProc, uengShaderPartText, uengShaderPartEcho, uengShaderPartIf, uengShaderPartInclude, uengShaderPartParameter, uengShaderPartComment, uengShaderFileConstants; const TOKEN_CLASSES: array[0..22] of CengShaderCodePart = ( TengShaderPartCall, TengShaderPartClass, TengShaderPartConst, TengShaderPartStatic, TengShaderPartLineBreak, TengShaderPartCommandEnd, TengShaderPartComment, TengShaderPartEcho, TengShaderPartError, TengShaderPartMain, TengShaderPartIf, TengShaderPartInclude, TengShaderPartInherited, TengShaderPartFunc, TengShaderPartInfo, TengShaderPartMeta, TengShaderPartProc, TengShaderPartProperty, TengShaderPartThrow, TengShaderPartUniform, TengShaderPartVar, TengShaderPartVarying, TengShaderPartWarning ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartCntr//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartCntr.HandleToken(const aToken: String; const aArgs: TengParseArgs): String; var p: TengShaderCodePart; c: CengShaderCodePart; begin p := nil; for c in TOKEN_CLASSES do begin if c.CheckToken(aToken) then begin c.Validate(aArgs, self); p := c.Create(self); AddChild(p); break; end; end; if Assigned(p) then result := p.ParseText(aArgs) else result := aToken; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartCntr.GetCount: Integer; begin result := fChildren.Count; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartCntr.GetChild(const aIndex: Integer): TengShaderPart; begin result := fChildren[aIndex]; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartCntr.GetText: String; var p: TengShaderPart; begin result := ''; for p in self do result := result + p.Text; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartCntr.ParseIntern(const aArgs: TengParseArgs; const aParams: TengTokenParameterList): String; var TextObj: TengShaderPartText; begin result := ''; fChildren.Clear; while not aArgs.EndOfFile and (result = '') do begin TextObj := TengShaderPartText.Create(self); try result := TextObj.ParseText(aArgs); if not TextObj.IsEmpty then AddChild(TextObj) else FreeAndNil(TextObj); except FreeAndNil(TextObj); raise; end; if (result <> '') then result := HandleToken(result, aArgs); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengShaderPartCntr.AddChild(const aChild: TengShaderCodePart; const aPrepend: Boolean); begin if aPrepend then fChildren.PushFirst(aChild) else fChildren.PushLast(aChild); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengShaderPartCntr.GenerateCodeIntern(const aArgs: TengShaderGeneratorArgs); var p: TengShaderCodePart; s: String; begin s := GetTokenName; if (s = '') then s := ClassName; aArgs.AddToken(s); try for p in fChildren do p.GenerateCodeIntern(aArgs); finally aArgs.AddToken(TOKEN_END); end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// procedure TengShaderPartCntr.Clear; begin fChildren.Clear; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// constructor TengShaderPartCntr.Create(const aParent: TengShaderPart); begin inherited Create(aParent); fChildren := TengShaderCodePartList.Create(true); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TengShaderPartCntr.Destroy; begin FreeAndNil(fChildren); inherited Destroy; end; end.