summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey C. Ollie <jeff@ocjtech.us>2025-08-16 00:29:26 -0500
committerMitchell Hashimoto <m@mitchellh.com>2025-08-18 09:20:40 -0700
commitdd072d2e01635003da49541489434ddf07b20523 (patch)
tree1f849c9d026e22865ee8b2f74db8a42acdc44c6d
parentf147a89b6839bc6c31d79befbf391375e51b50f9 (diff)
gtk-ng: add some initial notes on memory layout of GObjects
-rw-r--r--src/apprt/gtk-ng/class.zig42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/apprt/gtk-ng/class.zig b/src/apprt/gtk-ng/class.zig
index ee29954cb..b3ea70a37 100644
--- a/src/apprt/gtk-ng/class.zig
+++ b/src/apprt/gtk-ng/class.zig
@@ -53,13 +53,49 @@ pub fn Common(
}
}).private else {};
- /// Get the class structure for the object.
+ /// Get the class for the object.
///
- /// This seems ugly and unsafe to me but this is what GObject is doing
- /// under the hood.
+ /// This _seems_ ugly and unsafe but this is what GObject is doing
+ /// under the hood when it wants to access the class instance:
///
/// https://gitlab.gnome.org/GNOME/glib/-/blob/2c08654b62d52a31c4e4d13d7d85e12b989e72be/gobject/gtype.h#L555-571
/// https://gitlab.gnome.org/GNOME/glib/-/blob/2c08654b62d52a31c4e4d13d7d85e12b989e72be/gobject/gtype.h#L2673
+ ///
+ /// This works because when you create a new object in GObject, the pointer
+ /// that you get back wasn't allocated using your original type struct.
+ /// Instead you get the following block of data:
+ ///
+ ///
+ /// ┌─────────────────┐
+ /// │ │
+ /// │ │
+ /// │ Private │
+ /// │ │
+ /// │ │
+ /// │ │
+ /// │ │
+ /// ┌───►├─────────────────┤
+ /// *object────┘ │ │
+ /// │ TypeInstance │
+ /// │ │ ┌───►┌────────────────┐
+ /// │ │ │ │ │
+ /// │ │ │ │ Class │
+ /// │ *g_class ────┼───┘ │ │
+ /// │ │ │ │
+ /// └─────────────────┘ │ │
+ /// │ │
+ /// │ │
+ /// └────────────────┘
+ ///
+ /// First is a block of data that holds the instance's private data. That private
+ /// data is accessed by taking the instance pointer and subtracting the size of the
+ /// private data to get a pointer to the data.
+ ///
+ /// Next is an instance of a TypeInstance, whose purpose is to hold a pointer
+ /// to the class instance.
+ ///
+ /// https://gitlab.gnome.org/GNOME/glib/-/blob/2c08654b62d52a31c4e4d13d7d85e12b989e72be/gobject/gtype.c#L1792-1912
+ ///
pub fn getClass(self: *Self) ?*Self.Class {
const type_instance: *gobject.TypeInstance = @ptrCast(self);
return @ptrCast(type_instance.f_g_class orelse return null);