unit uengShaderPartIf; {$mode objfpc}{$H+} {$I uengShaderFile.inc} interface uses Classes, SysUtils, uengShaderPart, uengShaderPartCntr, uengShaderFileExpression, uengShaderFileParser; type //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengShaderPartIf = class(TengShaderPart) { Code Loading & Storage } private fExpression: TengExpressionItem; fIfPart: TengShaderPart; fElsePart: TengShaderPart; function HandleToken(const aToken: String; const aArgs: TengParseArgs): String; protected function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; virtual; 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; { General } public destructor Destroy; override; { Class Methods } public class function GetTokenName: String; override; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengShaderPartElIf = class(TengShaderPartIf) { Code Loading & Storage } protected function HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; override; { Class Methods } public class function GetTokenName: String; override; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// TengShaderPartElse = class(TengShaderPartCntr) { Code Loading & Storage } protected function GetText: String; override; { Class Methods } public class function GetTokenName: String; override; end; implementation uses uengShaderFileTypes, uengShaderFileConstants, uengShaderFileHelper; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartIf////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartIf.HandleToken(const aToken: String; const aArgs: TengParseArgs): String; const TOKEN_CLASSES: array[0..1] of CengShaderPart = ( TengShaderPartElse, TengShaderPartElIf ); var c: CengShaderPart; begin for c in TOKEN_CLASSES do begin if c.CheckToken(aToken) then begin c.Validate(aArgs, self); fElsePart := c.Create(self); break; end; end; if Assigned(fElsePart) then result := fElsePart.ParseText(aArgs); result := HandeEndToken(result, aArgs); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; begin result := CheckEndToken(aArgs, self); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartIf.GetCount: Integer; begin result := 1; if Assigned(fElsePart) then inc(result, 1); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartIf.GetChild(const aIndex: Integer): TengShaderPart; begin if (aIndex < 0) or (aIndex >= Count) then raise EengOutOfRange.Create(0, Count-1, aIndex, Line, Col, Filename); case aIndex of 0: result := fIfPart; 1: result := fElsePart; end; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartIf.GetText: String; begin result := TOKEN_CHAR_BEGIN + GetTokenName + ' ' + fExpression.GetText + TOKEN_CHAR_END + fIfPart.Text; if Assigned(fElsePart) then result := result + fElsePart.Text; result := result + TOKEN_CHAR_BEGIN + TOKEN_END + TOKEN_CHAR_END; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartIf.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); if (aParams.Count < 2) then raise EengInvalidParamterCount.Create(GetTokenName, 2, -1, Line, Col, Filename); fExpression := ParseExpression(aParams, 1); fIfPart := TengShaderPartCntr.Create(self); result := fIfPart.ParseText(aArgs); result := HandleToken(result, aArgs); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// destructor TengShaderPartIf.Destroy; begin FreeAndNil(fExpression); FreeAndNil(fIfPart); FreeAndNil(fElsePart); inherited Destroy; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function TengShaderPartIf.GetTokenName: String; begin result := TOKEN_IF; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartElIf//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartElIf.HandeEndToken(const aToken: String; const aArgs: TengParseArgs): String; begin result := aToken; if (result <> TOKEN_END) then raise EengInvalidToken.Create(ClassName, result, aArgs.Line, aArgs.Col, Filename); end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function TengShaderPartElIf.GetTokenName: String; begin result := TOKEN_ELIF; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TengShaderPartElse//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function TengShaderPartElse.GetText: String; begin result := TOKEN_CHAR_BEGIN + GetTokenName + TOKEN_CHAR_END + inherited GetText; end; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// class function TengShaderPartElse.GetTokenName: String; begin result := TOKEN_ELSE; end; end.