====== TObjectList — Liste von Objektverweisen ======
Eine wachsende Liste, die **Adressen** hält, keine Objekte. Vega benutzt sie überall dort, wo eine Klasse beliebig viele andere Objekte verwaltet: die Kinder eines [[lyx_-_programmiersprache:vega:controls:tcontrol|TControl]], die Spalten und Einträge einer [[lyx_-_programmiersprache:vega:controls:tlistview|TListView]], die Fenster einer [[lyx_-_programmiersprache:vega:controls:tapplication|TApplication]].
Unit: ''Vega.Lists''
→ [[lyx_-_programmiersprache:vega:controls|Alle Steuerelemente]] · [[lyx_-_programmiersprache:guides:speicher-praxis|Speicher in der Praxis]]
----
===== Einordnung =====
Lyx kennt keine generischen Klassen. Eine Liste je Elementtyp von Hand zu schreiben wäre derselbe Code in vielen Fassungen — deshalb hält ''TObjectList'' rohe Adressen (''int64''), und der Aufrufer castet beim Herausholen zurück:
var e: TEintrag := liste.Get(1) as TEintrag;
Das ist der Preis dafür, dass es die Liste überhaupt nur einmal gibt. Wer Zeichenketten braucht, nimmt ''TStringList''; wer Zahlen braucht, ''TIntArray'' — beide ebenfalls in ''Vega.Lists''.
----
===== Verwendung =====
unit Main;
import std.io;
import Vega.Types;
import Vega.Strings;
import Vega.Lists;
pub type TEintrag = class {
Nummer: int64;
fn Create(n: int64): void { self.Nummer := n; }
}
fn main(): int64 {
var liste: TObjectList := NewObjectList();
// Objekte anlegen und ihre Adressen ablegen
var i: int64 := 0;
while (i < 3) {
var e: TEintrag := new TEintrag(i * 10);
liste.Add(e as int64);
i := i + 1;
}
// Herausholen: die Liste liefert eine Adresse, der Aufrufer castet
var zweiter: TEintrag := liste.Get(1) as TEintrag;
PrintLn(StrConcat("zweiter: ", IntToStr(zweiter.Nummer)));
// Einfuegen, tauschen, suchen
var neu: TEintrag := new TEintrag(99);
liste.Insert(0, neu as int64);
liste.Exchange(0, 1);
PrintLn(StrConcat("Index von neu: ", IntToStr(liste.IndexOf(neu as int64))));
PrintLn(StrConcat("Anzahl: ", IntToStr(liste.Count)));
// Entfernen entfernt nur den VERWEIS — das Objekt lebt weiter
liste.Delete(0);
PrintLn(StrConcat("nach Delete: ", IntToStr(liste.Count)));
// Aufraeumen: erst die Eintraege, dann die Liste
var k: int64 := 0;
while (k < liste.Count) {
var obj: TEintrag := liste.Get(k) as TEintrag;
dispose obj;
k := k + 1;
}
dispose neu;
liste.Destroy();
return 0;
}
zweiter: 10
Index von neu: 1
Anzahl: 4
nach Delete: 3
Übersetzt und ausgeführt mit ''lyxc 1.1.3I''.
----
===== Besonderheiten =====
* **Die Liste gibt ihre Einträge nicht frei.** Es gibt keinen gemeinsamen Destruktor, den man über einen rohen Verweis aufrufen könnte. Wer die Objekte anlegt, räumt sie auch weg — ''Destroy()'' der Liste gibt nur ihren eigenen Speicher zurück.
* **''Delete'' und ''Clear'' entfernen nur den Verweis**, nicht das Objekt. Wer vorher nicht ''dispose'' ruft, hat ein Leck.
* ''Get(i)'' liefert bei ungültigem Index ''0'' statt abzustürzen — die Prüfung ''if (p != 0)'' lohnt sich, wenn der Index aus einer Berechnung stammt.
* **Der Speicher liegt auf dem Heap.** Als Inline-Feld in einer ''TControl''-Ableitung würde er in dessen Kinderfeld ragen ([[https://github.com/SEOLizer/LyX-Compiler/issues/1630|#1630]]) — deshalb immer als Objekt anlegen, nie als Inline-Array.
* Die Kapazität wächst in Zweierschritten ab ''VEGA_LIST_MIN_CAP'' (8). ''Reserve(n)'' nimmt das vorweg, wenn die Zahl der Einträge bekannt ist.
* ''Insert'' und ''Delete'' verschieben die folgenden Einträge — bei großen Listen in einer Schleife merkbar. ''Add'' ist billig.
----
===== Eigenschaften =====
Alle Eigenschaften, auch die geerbten.
^ Name ^ Typ ^ Bedeutung ^ Herkunft ^
| ''Items'' | [[lyx_-_programmiersprache:sprache:datentypen#1_ganzzahl-typen_signiert|int64]] | Die Einträge | eigen |
| ''Count'' | [[lyx_-_programmiersprache:sprache:datentypen#1_ganzzahl-typen_signiert|int64]] | Anzahl der Verweise | eigen |
| ''Capacity'' | [[lyx_-_programmiersprache:sprache:datentypen#1_ganzzahl-typen_signiert|int64]] | Platz, bevor die Liste wächst | eigen |
----
===== Methoden =====
Alle Methoden, auch die geerbten.
^ Signatur ^ Zweck ^ Herkunft ^
| ''Create(): void'' | Anlegen; ''NewObjectList()'' | eigen |
| ''Destroy(): void'' | Gibt den **eigenen** Speicher frei, nicht die Einträge | eigen |
| ''Reserve(n: int64): bool'' | Platz für ''n'' Einträge vorab belegen | eigen |
| ''Get(i: int64): int64'' | Verweis lesen; ''0'' bei ungültigem Index | eigen |
| ''Put(i: int64, obj: int64): void'' | Verweis ersetzen | eigen |
| ''Add(obj: int64): int64'' | Verweis anhängen, liefert den Index (''-1'' bei Speichermangel) | eigen |
| ''Insert(index: int64, obj: int64): int64'' | Verweis einfügen; der Index wird auf ''0''..''Count'' begrenzt | eigen |
| ''Delete(index: int64): void'' | Verweis entfernen, Folgende rücken auf | eigen |
| ''IndexOf(obj: int64): int64'' | Index eines Verweises; ''-1'', wenn nicht enthalten | eigen |
| ''Clear(): void'' | Alle Verweise vergessen (''Count := 0'') | eigen |
| ''Exchange(a: int64, b: int64): void'' | Zwei Einträge tauschen | eigen |
----
===== Ereignisse =====
Keine.
Letzte Aktualisierung: 2026-08-19 — API aus ''Vega/Lists.lyx'' erhoben, Beispiel mit ''lyxc 1.1.3I'' übersetzt und ausgeführt.