Einzelnen Beitrag anzeigen

Scurra

Registriert seit: 19. Jan 2015
81 Beiträge
 
Delphi 10.3 Rio
 
#20

AW: Canvas: Änderungen/Bewegungen zeichnen

  Alt 25. Dez 2019, 11:16
Hallo zusammen,

nach einer langen Pause habe ich mir nun endlich wieder die Zeit genommen, an diesem Projekt weiter zu arbeiten.

Aktuell beschäftigt mich immer noch das Zeichnen. Aktuell mache ich das folgendermaßen (ich benutze die GR32-Komponente):

Ich habe folgendes Interface, das mir den Inhalt der Radarfläche kapselt:
Delphi-Quellcode:
IRadarScreen = interface(IBaseInterface)
    function GetContent: TImage32;

    /// <summary>The image-information which shall be displayed.</summary>
    /// <remarks>The interface will free the content when implementation is freed. Do not
    /// hold a reference to the content unless you are sure that implementation lives longer than
    /// your reference!</remarks>
    property Content: TImage32 read GetContent;
  end;
Ganz innen habe ich einen Thread zum Zeichnen. Dieser erzeugt eine TImage32-Instanz mit den gewünschten Bitmap-Layern und verpackt diese Instanz im IRadarScreen-Interface. Über eine Callback-Methode reicht der Thread dieses Interface nach außen. Hier mein aktueller Code:
Delphi-Quellcode:
procedure TDrawerThread.Run;
var
  radarScreen: IRadarScreen;
begin
  inherited;

  while not Terminated do
  begin
    radarScreen := TestRadarScreenUpdate; // diese Methode erzeugt die TImage32-Instanz und liefert dieses als IRadarScreen-Interface zurück.
    if Assigned(FOnDrawSuccess) then
      Synchronize(procedure
                  begin
                    FOnDrawSuccess(radarScreen)
                  end);
    sleep(33);
  end;
end;
(Später soll dieser Code immer dann getriggert werden, wenn etwas neu gezeichnet werden muss, sei es durch eine Neuberechnung der Positionen in der Simulation oder durch ein Resize der Radar-Fläche. Die Prozedur FOnDrawSuccess wird per Constructor-Injection an den Thread übergeben)

Das IRadarScreen-Interface wird dann über verschiedene Schichten im Model an den Presenter und von dort an mein View übergeben. Das View hat schließlich Zugriff aufs Formular und führt bei einem Update folgenden Code aus:

Delphi-Quellcode:
procedure TMainView.SetRadarScreen(const UpdatedRadarScreen: IRadarScreen);
var
  radarScreenRefOld: IRadarScreen;
begin
  // ensure that the old IRadarScreen is freed only after the reference to its image has been removed!
  radarScreenRefOld := FRadarScreenRef;
  FRadarScreenRef := UpdatedRadarScreen;

  if Assigned(FRadarScreenContent) then
    FRadarScreenContent.Parent := nil;

  FRadarScreenContent := UpdatedRadarScreen.Content;
  radarScreenRefOld := nil;
  FRadarScreenContent.Parent := Form.pnlRadar;
  FRadarScreenContent.Left := 0;
  FRadarScreenContent.Top := 0;
end;
Kurz gesagt heißt das, dass ich immer die komplette TImage32-Instanz auf dem Formular austausche. Ich habe es schon einmal mit TImage32.Assign ausprobiert, aber das liefert eine Exception, weil man TImage32 das zuweisen auf diese Art wohl nicht unterstützt.
Da ich bisher noch kaum Erfahrung mit dem Zeichnen/Neuzeichnen habe, wollte ich mal fragen, ob meine Implementierung vllt. zu unerwünschten Effekten führen könnte (weil ich immer das komplette TImage32-Objekt austausche) und ob es da vllt. bessere Möglichkeiten gibt.
  Mit Zitat antworten Zitat