class, allen Instanzen ermitteln

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 6938
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

class, allen Instanzen ermitteln

Beitrag von Mathias »

Ist es möglich allen Instanzen einer Classe zu ermitteln und anschliessend in denen eine Methode auf zu rufen ?

Code: Alles auswählen

program project1;
 
uses
  SysUtils;
 
type
 
  { TVater }
 
  TVater = class(TObject)
  private
  var
    Shader: string;
  public
  const
    Licht: integer = 10;
    class procedure InitLicht(l:integer);;
    procedure In_Shader_Schreiben;
  end;
 
  { TVater }
 
  class procedure TVater.InitLicht(l: integer);
  var
    i: integer;
  begin
    Licht := l;
    for i := 0 to AnzahlInstanzen do begin   // geht so was ?
      In_Shader_Schreiben;
    end;
  end;
 
  procedure TVater.In_Shader_Schreiben;
  begin
    Shader := IntToStr(Licht);
    Writeln(Shader);
  end;
 
var
  Kind1: TVater;
  Kind2: TVater;
 
begin
  Kind1 := TVater.Create;
  Kind2 := TVater.Create;
 
  TVater.InitLicht(123);  // Bei allen Objecten in Shader schreiben
 
  Kind1.Free;
  Kind2.Free;
  Readln;
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: class, allen Instanzen ermitteln

Beitrag von theo »

Geht es denn nicht einfacher?

Code: Alles auswählen

 
uses contnrs;
...
var OL:TObjectList;
  i: Integer;
begin
  OL:=TObjectList.Create(true);
  OL.Add(TVater.Create);
  OL.Add(TVater.Create);
  OL.Add(TVater.Create);
  for i:=0 to OL.Count-1 do TVater(OL[i]).Tuwas;
  OL.free;
end;   

Mathias
Beiträge: 6938
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class, allen Instanzen ermitteln

Beitrag von Mathias »

Das mit der List hat mich auf eine Idee gebracht.

Ich will aber die Liste versteckt in der Classe haben, somit bin ich auf folgende Lösung gekommen.
Vielleicht könnte man die ObjectList auch unsichtbar in die Classe einbetten, aber ob das Sinn macht ?

Code: Alles auswählen

program project1;
 
uses
  SysUtils;
 
type
 
  { TVater }
 
  TVater = class(TObject)
  private
  const
    Licht: integer = 10;
  var
    Shader: string;
    Name: string;
    adr: Pointer;
    type TVaterList = array of TVater;
    class var VaterList: TVaterList;
 
    procedure In_Shader_Schreiben;
  public
    class procedure InitLicht(l: integer);
    constructor Create(n: string);
    destructor Free;
  end;
 
  { TVater }
 
  class procedure TVater.InitLicht(l: integer);
  var
    i: integer;
  begin
    Licht := l;
    for i := 0 to Length(VaterList) - 1 do begin
      VaterList[i].In_Shader_Schreiben;
    end;
    Writeln('---------');
  end;
 
  constructor TVater.Create(n: string);
  var
    l: integer;
  begin
    Name := n;
    adr := Pointer(self);
    l := Length(VaterList);
    SetLength(VaterList, l + 1);
    VaterList[l] := self;
  end;
 
  destructor TVater.Free;
  var
    i: integer;
 
    procedure DeleteA(var A: TVaterList; const Index: cardinal);
    var
      ALength, i: cardinal;
    begin
      ALength := Length(A);
      if (ALength > 0) and (Index < ALength) then begin
        for i := Index + 1 to ALength - 1 do begin
          A[i - 1] := A[i];
        end;
        SetLength(A, ALength - 1);
      end;
    end;
 
  begin
    for i := 0 to Length(VaterList) - 1 do begin
      if VaterList[i] = self then begin
        DeleteA(VaterList, i);
        break;
      end;
    end;
  end;
 
  procedure TVater.In_Shader_Schreiben;
  begin
    Shader := IntToStr(Licht);
    Writeln('Addr: ', integer(adr), ' Name: ', Name);
  end;
 
var
  Kind1: TVater;
  Kind2: TVater;
  Kind3: TVater;
  Kind4: TVater;
  Kind5: TVater;
 
begin
  Kind1 := TVater.Create('Kind1');
  Kind2 := TVater.Create('Kind2');
  Kind3 := TVater.Create('Kind3');
  Kind4 := TVater.Create('Kind4');
 
  TVater.InitLicht(123);  // Bei allen Objecten in Shader schreiben
 
  Kind3.Free;
 
  TVater.InitLicht(123);  // Bei allen Objecten in Shader schreiben
 
  Kind5 := TVater.Create('Kind5');
 
  TVater.InitLicht(123);  // Bei allen Objecten in Shader schreiben
 
  Kind1.Free;
 
  TVater.InitLicht(123);  // Bei allen Objecten in Shader schreiben
 
  Kind2.Free;
  Kind4.Free;
  Kind5.Free;
  TVater.InitLicht(123);  // Bei allen Objecten in Shader schreiben
  Readln;
end.
Ausgabe:

Code: Alles auswählen

Addr: 2443656 Name: Kind1
Addr: 2443688 Name: Kind2
Addr: 2443720 Name: Kind3
Addr: 2443752 Name: Kind4
---------
Addr: 2443656 Name: Kind1
Addr: 2443688 Name: Kind2
Addr: 2443752 Name: Kind4
---------
Addr: 2443656 Name: Kind1
Addr: 2443688 Name: Kind2
Addr: 2443752 Name: Kind4
Addr: 2443720 Name: Kind5
---------
Addr: 2443688 Name: Kind2
Addr: 2443752 Name: Kind4
Addr: 2443720 Name: Kind5
---------
---------
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10904
Registriert: Mo 11. Sep 2006, 19:01

Re: class, allen Instanzen ermitteln

Beitrag von theo »

Aber wozu soll das gut sein?
Es ist kompliziert, die Pointer werden doppelt gehalten (Variablen und Liste) und ich erkenne den Vorteil nicht, der diese Nachteile aufwiegt.
Also was sind deine Überlegungen?

Mathias
Beiträge: 6938
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class, allen Instanzen ermitteln

Beitrag von Mathias »

Es geht um verschiedene Körper in OpenGL. Da gibt es eine Basis-Classe für die verschiedenen Körper. Jede Instanz bekommt einen eigene Shader. Die verschiedenen Körper sind Nachkommen von der Basis-Classe. Wen ich die Position des Lichtes ändere, muss ich dies via Unformübergabe in alle Shader schreiben.

Code: Alles auswählen

...
private
    Cylinder: TTexturCylinder;
    TexturCube: TTexturCube;
    CTriangle: TColorTriangle;
    Cube: TCube; 
... 
Das sind alles Nachkommen von TTexturKorper.

Wen ich dann die Lichtposition ändere, muss ich dann nur noch

Code: Alles auswählen

TTexturKoerper.LightPos(...)
aufrufen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: class, allen Instanzen ermitteln

Beitrag von mschnell »

Mathias hat geschrieben:Ist es möglich allen Instanzen einer Classe zu ermitteln und anschliessend in denen eine Methode auf zu rufen ?
Man kann ein Array vom Typ dieser Klasse als Klassen-Variable machen und im Creator die gerade erzeugte Instanz eintragen und im Destructor die zu zerstörende Instanz im Array löschen.

Eine (Klassen-) Funktion kann dann durch alle existierenden Instanzen laufen und für jede einen Callback aufrufen.

-Michael

Mathias
Beiträge: 6938
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: class, allen Instanzen ermitteln

Beitrag von Mathias »

Man kann ein Array vom Typ dieser Klasse als Klassen-Variable machen und im Creator die gerade erzeugte Instanz eintragen und im Destructor die zu zerstörende Instanz im Array löschen.

Eine (Klassen-) Funktion kann dann durch alle existierenden Instanzen laufen und für jede einen Callback aufrufen.
Ist das nicht, was ich im 2. Code gemacht habe ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten