Delphi XE2

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!!!

Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • Paolo Ingraito  Il 24 gennaio 2012 alle 00:24

    Io invece sviluppando “by myself” lo adotto in pieno; la possibilità di avere il proprio programma direttamente anche in MAC OS per me è un’opportunità irrinunciabile.
    Come ti avevo accennato io mi trovo molto bene a limitare le sessioni di ridisegno attraverso un Timer (che potrebbe essere anche messo dentro un thread, anche se ho come l’impressione che in Firemonkey il Timer crei dei thread virtuali), che limita l’aggiornamento dell’immagine ogni tot di tempo.

    • dikiyvolk  Il 24 gennaio 2012 alle 09:43

      La tua idea sul timer ha un certo fondamento… il timer come oggetto è tipico di windows e ai tempi di windows 3.1 erano molto limitati, per cui dovendo fare qualche cosa di portabile da un S.O. ad un altro è possibile che abbiano rivisto questa classe. Una domanda… e sviluppare direttamente in objective-c? Bisogna affrontare un paio di scogli iniziali di XCode che assomiglia un po’ ai vecchi ide di IBM del progetto VisualAge però poi le cose vanno lisce e sfrutteresti appieno il S.O.

  • Paolo Ingraito  Il 24 gennaio 2012 alle 12:14

    Ho studiato un po’ il C, proprio con questo obiettivo, ma la sintassi, l’uso esagerato dei puntatori, la manzanza di un ide che mi entuasmi, i file h e mille altre cose del genere me l’hanno reso molto antipatico.

    Quando ho riscoperto Delphi mi sono sentito subito a casa, avevo fatto un mediaplayer quando facevo il liceo, con un accozzaglia di componenti di terze parti 🙂

    Se proprio dovessi cambiare linguaggio mi butterei sul C# che ha delle caratteristiche simili a Delphi, essendo ideato dallo stesso autore.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: