Rieccomi a bomba su Delphi XE2 e Firemonkey. Mi sembra di essere un post della serie Frattanto… o una puntata di Dallas, non ho mai scritto così tanto e tanto velocemente sul blog. Dopo un fine settimana di mail con Paolo che aveva commentato il precedente post ho corretto alcuni miei errori.
Nel test di firemonkey ho impropriamente usato un oggetto TRectangle, la cui creazione inseriva un overhead rispetto alla versione VCL che usava una funzione nativa dell’oggetto Canvas.
In soldoni
il codice
... Layout1.Canvas.BeginScene; with TRectangle.Create(Layout1) do begin ...
Spende molto tempo a creare l’oggetto che al tempo stesso è paragonabile ad un oggetto d’interfaccia ed è per questo che il bottone “Disegna” veniva ricoperto. Quindi dopo una chicchierata via mail con Paolo e qualche “inno” sacro notte tempo sono riuscito a scrivere sul mio oggetto canvas in modalità VCL style e a rendere quindi i due sorgenti comparabili.
constructor DrawFillRect.Create(ext_Image: TImage);
begin
inherited Create(true);
Layout1 := ext_Image;
IntWidth := Round(Layout1.Width);
IntHeight := Round(Layout1.Height);
arrayColor[1] := TAlphaColorRec.Alpha;
arrayColor[2] := TAlphaColorRec.Aliceblue;
...
...
arrayColor[153] := TAlphaColorRec.Yellow;
arrayColor[154] := TAlphaColorRec.Yellowgreen;
end;
procedure DrawFillRect.Execute;
var
i: integer;
dStartTime, dEndTime: TDateTime;
begin
dStartTime := now;
iShape := 1;
for i := 1 to MAX_NUM_OF_SHAPES do
synchronize(aggiorna);
dEndTime := now;
showmessage('Inizio : ' + formatDateTime('dd-mm-yyyy hh:nn:ss:zzz', dStartTime) + #13#10 +
'Fine : ' + formatDateTime('dd-mm-yyyy hh:nn:ss:zzz', dEndTime) + #13#10 +
'Trascorso: ' + formatDateTime('hh:nn:ss:zzz', dEndTime - dStartTime) + #13#10);
end;
procedure DrawFillRect.aggiorna;
var
iColor, iXCoord, iYCoord: integer;
MyRect, MyDrawRect: TRectF;
i: integer;
begin
with Layout1 do
begin
Canvas.BeginScene;
MyRect.Create(RandomRange(0, IntWidth), RandomRange(0, IntHeight),
RandomRange(0, IntWidth), RandomRange(0, IntHeight));
Canvas.fill.Color := arrayColor[RandomRange(1, 154)];
Canvas.FillRect(MyRect, 0, 0, AllCorners, 100);
Canvas.EndScene;
end;
end;
Notate le istruzioni:
Canvas.BeginScene; ... Canvas.EndScene;
se non si mettono non verrà disegnato nulla
(sigh questo è stato il mio grave errore). Comunque anche in questo caso il tempo non brilla… siamo a 31,117 s per cui non troppo meglio di prima
Inoltre spostando la mail con il thread in esecuzione la creazione dei rettangoli si blocca. Paolo mi suggerisce quindi di mettere il loop all’interno del blocco BeginScene…EndScene. Ottenendo quindi il seguente codice:
constructor DrawClearRectIntFor.Create(ext_Image: TImage);
begin
inherited Create(true);
Layout1 := ext_Image;
IntWidth := Round(Layout1.Width);
IntHeight := Round(Layout1.Height);
arrayColor[1] := TAlphaColorRec.Alpha;
arrayColor[2] := TAlphaColorRec.Aliceblue;
...
...
arrayColor[153] := TAlphaColorRec.Yellow;
arrayColor[154] := TAlphaColorRec.Yellowgreen;
end;
procedure DrawClearRectIntFor.Execute;
var
i: integer;
dStartTime, dEndTime: TDateTime;
begin
dStartTime := now;
iShape := 1;
synchronize(aggiorna);
dEndTime := now;
showmessage('Inizio : ' + formatDateTime('dd-mm-yyyy hh:nn:ss:zzz', dStartTime) + #13#10 +
'Fine : ' + formatDateTime('dd-mm-yyyy hh:nn:ss:zzz', dEndTime) + #13#10 +
'Trascorso: ' + formatDateTime('hh:nn:ss:zzz', dEndTime - dStartTime) + #13#10);
end;
procedure DrawClearRectIntFor.aggiorna;
var
iColor, iXCoord, iYCoord: integer;
MyRect, MyDrawRect: TRectF;
i: integer;
begin
for i := 1 to MAX_NUM_OF_SHAPES do
with Layout1.Bitmap do
begin
MyRect.Create(RandomRange(0, IntWidth), RandomRange(0, IntHeight),
RandomRange(0, IntWidth), RandomRange(0, IntHeight));
MyDrawRect.Create(MyRect.Left-1, MyRect.Top-1, MyRect.Right+1,MyRect.Bottom+1);
ClearRect(MyDrawRect, arrayColor[9] );
ClearRect(MyRect, arrayColor[RandomRange(1, 154)] );
BitmapChanged;
end;
end;
I risultati cambiano drasticamente solo 0,016 s ma non vedo più la fase di disegno, mi compare direttamente la chiazza di rettangoli colorati. Praticamente il blocco BeginScene..EndScene mi apre e chiude una fase di disegno che verra riportata a video… l’help ufficiale riporta per la EndScene:
Description Notifies the TCanvas object that the drawing is complete. Call EndScene after the drawing on the TCanvas is complete. To start the drawing session, call BeginScene.
Intanto Embarcadero sta valutando le mie segnalazioni (si mi hanno risposto) e anche loro sono sorpresi. Mi hanno detto che a breve uscira il quarto update di Firemonkey.
Il mio amico Juhan mi ha chiesto un parere finale a tutti questi articoli… Come ho scritto ad Embarcadero io credo che la Firemonkey sia notevole, aprirà certamente delle enormi possibilità per lo sviluppo multipiattaforma, ma come IT manager non posso proporlo ancora come alternativa alla VCL in ambiente di produzione.
Infatti il prodotto non è ancora maturo e stabile (4 update in poco tempo) e costo elevato di apprendimento (poca documentazione e troppe differenze dalla VCL). Però credo che andrà tenuto d’occhio!!!








