Sto costruendo un'applicazione Delphi che visualizza un progetto di un edificio, tra cui porte, finestre, cablaggio, illuminazione, prese, interruttori, ecc. Ho implementato uno script molto leggero per richiamare i comandi di disegno sulla tela , che viene caricato da un database. Ad esempio, un comando è ELP 1110,1110,1290,1290,3,8388608
che disegna un'ellisse, i parametri sono da 1110x1110 a 1290x1290 con la larghezza della penna di 3 e il colore 8388608
convertito da un numero intero a un TColor
.
Quello che sto facendo ora è implementare oggetti con routine di disegno comuni, e mi piacerebbe usare il mio motore di scripting, ma questo richiede dichiarazioni IF/THEN/ELSE
e così via. Ad esempio, quando disegno una luce, se la luce è accesa, mi piacerebbe disegnarla in giallo, ma se è spenta, mi piacerebbe disegnarla in grigio. Il mio attuale motore di scripting non ha riconoscimento di tali affermazioni. Accetta solo comandi di disegno semplici che corrispondono ai metodi TCanvas
.
Ecco la procedura che ho sviluppato (incompleto) per eseguire un comando di disegno su una tela:
function DrawCommand(const Cmd: String; var Canvas: TCanvas): Boolean;
type
TSingleArray = array of Single;
var
Br: TBrush;
Pn: TPen;
X: Integer;
P: Integer;
L: String;
Inst: String;
T: String;
Nums: TSingleArray;
begin
Result:= False;
Br:= Canvas.Brush;
Pn:= Canvas.Pen;
if Assigned(Canvas) then begin
if Length(Cmd) > 5 then begin
L:= UpperCase(Cmd);
if Pos(' ', L)> 0 then begin
Inst:= Copy(L, 1, Pos(' ', L) - 1);
Delete(L, 1, Pos(' ', L));
L:= L + ',';
SetLength(Nums, 0);
X:= 0;
while Pos(',', L) > 0 do begin
P:= Pos(',', L);
T:= Copy(L, 1, P - 1);
Delete(L, 1, P);
SetLength(Nums, X + 1);
Nums[X]:= StrToFloatDef(T, 0);
Inc(X);
end;
Br.Style:= bsClear;
Pn.Style:= psSolid;
Pn.Color:= clBlack;
if Inst = 'LIN' then begin
Pn.Width:= Trunc(Nums[4]);
if Length(Nums) > 5 then begin
Br.Style:= bsSolid;
Br.Color:= Trunc(Nums[5]);
end;
Canvas.MoveTo(Trunc(Nums[0]), Trunc(Nums[1]));
Canvas.LineTo(Trunc(Nums[2]), Trunc(Nums[3]));
Result:= True;
end else
if Inst = 'ELP' then begin
Pn.Width:= Trunc(Nums[4]);
if Length(Nums) > 5 then begin
Br.Style:= bsSolid;
Br.Color:= Trunc(Nums[5]);
end;
Canvas.Ellipse(Trunc(Nums[0]),Trunc(Nums[1]),Trunc(Nums[2]),Trunc(Nums[3]));
Result:= True;
end else
if Inst = 'ARC' then begin
Pn.Width:= Trunc(Nums[8]);
Canvas.Arc(Trunc(Nums[0]),Trunc(Nums[1]),Trunc(Nums[2]),Trunc(Nums[3]),
Trunc(Nums[4]),Trunc(Nums[5]),Trunc(Nums[6]),Trunc(Nums[7]));
Result:= True;
end else
if Inst = 'TXT' then begin
Canvas.Font.Size:= Trunc(Nums[2]);
Br.Style:= bsClear;
Pn.Style:= psSolid;
T:= Cmd;
Delete(T, 1, Pos(' ', T));
Delete(T, 1, Pos(',', T));
Delete(T, 1, Pos(',', T));
Delete(T, 1, Pos(',', T));
Canvas.TextOut(Trunc(Nums[0]), Trunc(Nums[1]), T);
Result:= True;
end;
end else begin
//No space found, not a valid command
end;
end;
end;
end;
Quello che mi piacerebbe sapere è che cos'è un buon motore di scripting di terze parti leggero che potrei usare per realizzare questo? Non vorrei implementare l'analisi di IF
, THEN
, ELSE
, END
, IFELSE
, IFEND
e tutti quei comandi necessari. Ho semplicemente bisogno della capacità di dire al motore di scripting se determinate proprietà soddisfano determinate condizioni, è necessario disegnare l'oggetto in un determinato modo.
L'esempio di luce sopra è solo uno scenario, ma la stessa soluzione deve essere applicabile anche ad altri scenari, come una porta aperta o chiusa, bloccata o sbloccata, e disegnarla di conseguenza in modo diverso. Questo deve essere implementato nel livello di disegno dello script dell'oggetto. Non riesco a codificare hard nessuna di queste regole di scripting / drawing, il disegno deve essere controllato in base allo stato corrente dell'oggetto, e potrei anche desiderare di disegnare una luce di una certa tonalità o oscurità a seconda di quanto attenuata la luce è.