Kerntypen

Godot hat eine Vielzahl von Klassen und Vorlagen, aus denen sich sein Kern zusammensetzt, und alles baut darauf auf.

Diese Referenz wird versuchen sie aufzulisten, um sie besser zu verstehen.

Definitionen

Godot uses the standard C99 datatypes, such as uint8_t, uint32_t, int64_t, etc. which are nowadays supported by every compiler. Reinventing the wheel for those is not fun, as it makes code more difficult to read.

In general, care is not taken to use the most efficient datatype for a given task unless using large structures or arrays. int is used through most of the code unless necessary. This is done because nowadays every device has at least a 32 bits bus and can do such operations in one cycle. It makes code more readable too.

For files or memory sizes, size_t is used, which is warranted to be 64 bits.

For Unicode characters, CharType instead of wchar_t is used, because many architectures have 4 bytes long wchar_t, where 2 bytes might be desired. However, by default, this has not been forced and CharType maps directly to wchar_t.

Referenzen:

Speichermodell

PC ist eine wunderbare Architektur. Computer verfügen häufig über Gigabytes an RAM, Terabytes an Speicher und Gigahertz CPU. Wenn eine Anwendung mehr Ressourcen benötigt, lagert das Betriebssystem die inaktiven aus. Andere Architekturen (wie Mobilgeräte oder Konsolen) sind im Allgemeinen eingeschränkter.

Das gebräuchlichste Speichermodell ist der Heap, bei dem eine Anwendung einen Speicherbereich anfordert und das zugrunde liegende Betriebssystem versucht, ihn irgendwo anzupassen und zurückzugeben. Dies funktioniert oft am besten und ist flexibel, aber im Laufe der Zeit und bei Missbrauch kann dies zu einer Segmentierung führen.

Durch die Segmentierung werden langsam Löcher erzeugt, die für die meisten gängigen Zuordnungen zu klein sind, sodass Speicherplatz verschwendet wird. Es gibt viel Literatur über Heap und Segmentierung, daher wird auf dieses Thema hier nicht weiter eingegangen. Moderne Betriebssysteme verwenden ausgelagerten Speicher, wodurch das Segmentierungsproblem zwar gemindert, aber nicht gelöst wird.

In vielen Studien und Tests wurde jedoch gezeigt, dass bei ausreichendem Speicher die Segmentierung im Laufe der Zeit kein Problem darstellt, wenn die maximale Zuordnungsgröße im Verhältnis zur maximalen Heap-Größe und zum Anteil des Speichers, der nicht verwendet werden soll, unter einem bestimmten Schwellenwert liegt wie es konstant bleiben wird. Mit anderen Worten, lassen Sie 10-20% Ihres Speichers frei und führen Sie alle kleinen Zuweisungen durch, und alles ist gut.

Godot ensures that all objects that can be allocated dynamically are small (less than a few kb at most). But what happens if an allocation is too large (like an image or mesh geometry or large array)? In this case Godot has the option to use a dynamic memory pool. This memory needs to be locked to be accessed, and if an allocation runs out of memory, the pool will be rearranged and compacted on demand. Depending on the need of the game, the programmer can configure the dynamic memory pool size.

Speicher zuweisen

Godot verfügt über viele Tools zum Verfolgen der Speichernutzung in einem Spiel, insbesondere während des Debuggens. Aus diesem Grund sollten die regulären C und C++ Bibliotheksaufrufe nicht verwendet werden. Stattdessen werden einige andere bereitgestellt.

Für die Zuweisung im C-Stil bietet Godot einige Makros:

memalloc()
memrealloc()
memfree()

Diese entsprechen dem üblichen malloc, realloc, freigeben aus der Standard C-Bibliothek.

Für die Zuweisung im C++ Stil stehen spezielle Makros zur Verfügung:

memnew( Class / Class(args) )
memdelete( instance )

memnew_arr( Class , amount )
memdelete_arr( pointer to array )

die äquivalent zu new, delete, new [] und delete [] sind.

memnew/memdelete also use a little C++ magic and notify Objects right after they are created, and right before they are deleted.

For dynamic memory, the PoolVector<> template is provided. PoolVector is a standard vector class, and is very similar to vector in the C++ standard library. To create a PoolVector buffer, use this:

PoolVector<int> data;

PoolVector can be accessed using the [] operator and a few helpers exist for this:

PoolVector<int>::Read r = data.read()
int someint = r[4]
PoolVector<int>::Write w = data.write()
w[4] = 22;

These operations allow fast read/write from PoolVectors and keep it locked until they go out of scope. However, PoolVectors should be used for small, dynamic memory operations, as read() and write() are too slow for a large amount of accesses.

Container

Godot bietet auch eine Reihe gängiger Container:

  • Vektor
  • List
  • Set
  • Map

Sie sind einfach und sollen so minimal wie möglich zu sein, da Vorlagen in C++ häufig inline sind und die Binärgröße sowohl in Debug-Symbolen als auch den Code aufblähen. List, Set und Map können mit folgenden Zeigern iteriert werden:

for(List<int>::Element *E=somelist.front();E;E=E->next()) {
    print_line(E->get()); // print the element
}

Die Vector<> -Klasse hat auch ein paar nette Funktionen:

  • Sie kopiert beim Schreiben, daher ist das Erstellen von Kopien günstig, solange sie nicht geändert werden.
  • Sie unterstützt Multithreading durch Verwendung kleinster Operationen am Referenzzähler.

Zeichenkette

Godot bietet auch eine String-Klasse. Diese Klasse bietet eine Vielzahl von Funktionen, vollständige Unicode-Unterstützung für alle Funktionen (z.B. Falloperationen) und das Parsen bzw. Extrahieren von utf8 sowie Helfer für die Konvertierung und Visualisierung.

Referenzen:

StringName

StringNames sind wie ein String, sind aber eindeutig. Das Erstellen eines StringName aus einem String führt zu einem eindeutigen internen Zeiger für alle gleichen Strings. StringNames sind nützlich um Strings als Bezeichner zu verwenden, da beim Vergleich im Grunde genommen ein Zeiger verglichen wird.

Die Erstellung eines StringName (insbesondere eines neuen) ist langsam, der Vergleich jedoch schnell.

Referenzen:

Mathe-Typen

Im Verzeichnis core/math stehen mehrere lineare Mathe-Typen zur Verfügung.

Referenzen:

NodePath

Dies ist ein spezieller Datentyp, mit dem Pfade in einem Szenenbaum gespeichert und schnell referenziert werden.

Referenzen:

RID

RIDs sind Ressourcen-IDs. Server verwenden diese um auf darin gespeicherte Daten zu verweisen. RIDs sind undurchsichtig, was bedeutet, dass auf verwiesene Daten nicht direkt zugegriffen werden kann. RIDs sind eindeutig, auch für verschiedene Arten von Daten, auf die verwiesen wird.

Referenzen: