ffi M3.3 + M3.4 + M3.5: SxGLView/SxMetalView migrated; uikit_register_classes deleted
Three slices in one commit since they're tightly coupled (the
M3.5 deletion only makes sense after M3.3 and M3.4):
M3.3 — SxGLView migrated to declarative '#objc_class("SxGLView")':
- '#extends UIView' for the view-hierarchy + responder chain.
- 'layerClass :: *void = objc_getClass("CAEAGLLayer".ptr);' uses
the M2.1(a) class-level constant form. Registered on the
metaclass; UIView's +layerClass override dispatches here so
EAGL gets the right backing layer.
- Six instance methods (sxTick, layoutSubviews, four touch
selectors) forward to existing legacy IMP free functions.
M3.4 — SxMetalView migrated, same shape as SxGLView; differs only
in the 'layerClass' constant returning CAMetalLayer instead of
CAEAGLLayer. The five shared IMPs (sxTick/layoutSubviews/4 touch
handlers) reach the same free functions — they already branch on
plat.gpu_mode for GL-specific renderbuffer code.
M3.5 — uikit_register_classes() and the two helper registration
functions are deleted outright. Every sx-defined Obj-C class in
this module now goes through the compiler's M1.2 / M2.1(a)
synthesis path at module init. The call site inside
UIKitPlatform.init is gone too — just a comment marking the
migration point.
Chess on iOS-sim: board renders, scene-delegate connection still
fires, GL/Metal layer setup intact, touch dispatch routes through
the synthesized IMP trampolines. 183 example tests + zig build
test green.
End of M3. The platform layer's Obj-C-runtime wiring is fully
declarative.
Remaining: M4 (autoreleasepool + ARC ops), M5 (closure↔block),
M6 (auto-import + production hardening). M1.1.b (Class(T)
parameterization + instancetype) is still deferred — none of
the migrated uikit code needed it.
This commit is contained in:
@@ -313,7 +313,9 @@ impl Platform for UIKitPlatform {
|
||||
// happen BEFORE any code that loads fonts/textures from disk.
|
||||
inline if OS == .ios {
|
||||
uikit_chdir_to_bundle();
|
||||
uikit_register_classes();
|
||||
// M3.5 — uikit_register_classes was deleted. Every
|
||||
// sx-defined Obj-C class in this module is now declarative;
|
||||
// the compiler synthesises class-pair init at module init.
|
||||
if self.gpu_mode == .gles {
|
||||
uikit_create_gl_context(self);
|
||||
} else {
|
||||
@@ -450,19 +452,12 @@ uikit_chdir_to_bundle :: () {
|
||||
chdir(c_string(rsrc));
|
||||
}
|
||||
|
||||
uikit_register_classes :: () {
|
||||
inline if OS == .ios {
|
||||
// SxAppDelegate (M3.1) + SxSceneDelegate (M3.2) are now
|
||||
// declarative `#objc_class(...)` blocks — the compiler
|
||||
// synthesises their IMPs, class-pair registration, and
|
||||
// protocol conformances at module init. The old hand-rolled
|
||||
// objc_allocateClassPair + class_addMethod + class_addProtocol
|
||||
// sequences are gone.
|
||||
|
||||
uikit_register_gl_view_class();
|
||||
uikit_register_metal_view_class();
|
||||
}
|
||||
}
|
||||
// uikit_register_classes — deleted (M3.5). Every sx-defined
|
||||
// Obj-C class in this module (SxAppDelegate, SxSceneDelegate,
|
||||
// SxGLView, SxMetalView) is now a declarative `#objc_class(...)`
|
||||
// block — the compiler synthesises their IMPs, class-pair
|
||||
// registration, ivar wiring, +alloc / -dealloc trampolines, and
|
||||
// `#implements` protocol conformances at module init.
|
||||
|
||||
// Read [UIScreen mainScreen].nativeScale into plat.dpi_scale. Used by the
|
||||
// metal-mode init path which doesn't go through uikit_create_gl_context
|
||||
@@ -757,9 +752,39 @@ uikit_present_renderbuffer :: (self: *UIKitPlatform) {
|
||||
// ── SxGLView class ─────────────────────────────────────────────────────────
|
||||
// UIView subclass overriding `+layerClass` to return [CAEAGLLayer class].
|
||||
// Instance method `sxTick:` is what CADisplayLink calls.
|
||||
//
|
||||
// M3.3 — migrated to declarative `#objc_class` form. The compiler
|
||||
// synthesises class-pair init, metaclass `+layerClass`, and the
|
||||
// instance-method IMP trampolines at module init.
|
||||
SxGLView :: #objc_class("SxGLView") {
|
||||
#extends UIView;
|
||||
|
||||
uikit_gl_view_layer_class :: (cls: *void, _cmd: *void) -> *void callconv(.c) {
|
||||
objc_getClass("CAEAGLLayer".ptr);
|
||||
// Class-level constant — `+layerClass` returns [CAEAGLLayer class].
|
||||
layerClass :: *void = objc_getClass("CAEAGLLayer".ptr);
|
||||
|
||||
sxTick :: (self: *Self, link: *void) {
|
||||
uikit_gl_view_tick(xx self, xx 0, link);
|
||||
}
|
||||
|
||||
layoutSubviews :: (self: *Self) {
|
||||
uikit_gl_view_layout(xx self, xx 0);
|
||||
}
|
||||
|
||||
touchesBegan_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_began(xx self, xx 0, touches, event);
|
||||
}
|
||||
|
||||
touchesMoved_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_moved(xx self, xx 0, touches, event);
|
||||
}
|
||||
|
||||
touchesEnded_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_ended(xx self, xx 0, touches, event);
|
||||
}
|
||||
|
||||
touchesCancelled_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_ended(xx self, xx 0, touches, event);
|
||||
}
|
||||
}
|
||||
|
||||
uikit_gl_view_tick :: (self: *void, _cmd: *void, link_raw: *void) callconv(.c) {
|
||||
@@ -889,82 +914,44 @@ uikit_gl_view_touches_ended :: (self: *void, _cmd: *void, touches: *void, event:
|
||||
g_uikit_plat.events.append(.mouse_up(.{ position = pos, button = .left }));
|
||||
}
|
||||
|
||||
uikit_register_gl_view_class :: () {
|
||||
inline if OS == .ios {
|
||||
UIView := objc_getClass("UIView".ptr);
|
||||
SxGLView := objc_allocateClassPair(UIView, "SxGLView".ptr, 0);
|
||||
|
||||
// +layerClass is a CLASS method — registered on the metaclass.
|
||||
metaclass := object_getClass(SxGLView);
|
||||
class_addMethod(metaclass,
|
||||
sel_registerName("layerClass".ptr),
|
||||
xx uikit_gl_view_layer_class, "#@:".ptr);
|
||||
|
||||
// -sxTick: is the CADisplayLink callback. -layoutSubviews allocates
|
||||
// the renderbuffer when the layer first gets non-zero bounds.
|
||||
class_addMethod(SxGLView,
|
||||
sel_registerName("sxTick:".ptr),
|
||||
xx uikit_gl_view_tick, "v@:@".ptr);
|
||||
class_addMethod(SxGLView,
|
||||
sel_registerName("layoutSubviews".ptr),
|
||||
xx uikit_gl_view_layout, "v@:".ptr);
|
||||
|
||||
// Touch dispatch.
|
||||
class_addMethod(SxGLView,
|
||||
sel_registerName("touchesBegan:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_began, "v@:@@".ptr);
|
||||
class_addMethod(SxGLView,
|
||||
sel_registerName("touchesMoved:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_moved, "v@:@@".ptr);
|
||||
class_addMethod(SxGLView,
|
||||
sel_registerName("touchesEnded:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_ended, "v@:@@".ptr);
|
||||
class_addMethod(SxGLView,
|
||||
sel_registerName("touchesCancelled:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_ended, "v@:@@".ptr);
|
||||
|
||||
objc_registerClassPair(SxGLView);
|
||||
}
|
||||
}
|
||||
|
||||
// +layerClass IMP for SxMetalView. Class method, signature "#@:".
|
||||
uikit_metal_view_layer_class :: (cls: *void, _cmd: *void) -> *void callconv(.c) {
|
||||
objc_getClass("CAMetalLayer".ptr);
|
||||
}
|
||||
// uikit_register_gl_view_class — deleted (M3.3). SxGLView is now
|
||||
// declarative; the compiler synthesises everything at module init.
|
||||
|
||||
// SxMetalView reuses the same tick/layout/touch IMPs as SxGLView. The IMPs
|
||||
// already branch on `plat.gpu_mode` for the GL-specific bits (renderbuffer
|
||||
// setup, etc.), so a single set of IMPs serves both view classes.
|
||||
uikit_register_metal_view_class :: () {
|
||||
inline if OS == .ios {
|
||||
UIView := objc_getClass("UIView".ptr);
|
||||
SxMetalView := objc_allocateClassPair(UIView, "SxMetalView".ptr, 0);
|
||||
//
|
||||
// M3.4 — migrated to declarative `#objc_class`. Only `+layerClass`
|
||||
// differs from SxGLView (returns CAMetalLayer instead of CAEAGLLayer).
|
||||
SxMetalView :: #objc_class("SxMetalView") {
|
||||
#extends UIView;
|
||||
|
||||
metaclass := object_getClass(SxMetalView);
|
||||
class_addMethod(metaclass,
|
||||
sel_registerName("layerClass".ptr),
|
||||
xx uikit_metal_view_layer_class, "#@:".ptr);
|
||||
layerClass :: *void = objc_getClass("CAMetalLayer".ptr);
|
||||
|
||||
class_addMethod(SxMetalView,
|
||||
sel_registerName("sxTick:".ptr),
|
||||
xx uikit_gl_view_tick, "v@:@".ptr);
|
||||
class_addMethod(SxMetalView,
|
||||
sel_registerName("layoutSubviews".ptr),
|
||||
xx uikit_gl_view_layout, "v@:".ptr);
|
||||
sxTick :: (self: *Self, link: *void) {
|
||||
uikit_gl_view_tick(xx self, xx 0, link);
|
||||
}
|
||||
|
||||
class_addMethod(SxMetalView,
|
||||
sel_registerName("touchesBegan:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_began, "v@:@@".ptr);
|
||||
class_addMethod(SxMetalView,
|
||||
sel_registerName("touchesMoved:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_moved, "v@:@@".ptr);
|
||||
class_addMethod(SxMetalView,
|
||||
sel_registerName("touchesEnded:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_ended, "v@:@@".ptr);
|
||||
class_addMethod(SxMetalView,
|
||||
sel_registerName("touchesCancelled:withEvent:".ptr),
|
||||
xx uikit_gl_view_touches_ended, "v@:@@".ptr);
|
||||
layoutSubviews :: (self: *Self) {
|
||||
uikit_gl_view_layout(xx self, xx 0);
|
||||
}
|
||||
|
||||
objc_registerClassPair(SxMetalView);
|
||||
touchesBegan_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_began(xx self, xx 0, touches, event);
|
||||
}
|
||||
|
||||
touchesMoved_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_moved(xx self, xx 0, touches, event);
|
||||
}
|
||||
|
||||
touchesEnded_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_ended(xx self, xx 0, touches, event);
|
||||
}
|
||||
|
||||
touchesCancelled_withEvent :: (self: *Self, touches: *void, event: *void) {
|
||||
uikit_gl_view_touches_ended(xx self, xx 0, touches, event);
|
||||
}
|
||||
}
|
||||
|
||||
// uikit_register_metal_view_class — deleted (M3.4). Replaced by
|
||||
// the declarative SxMetalView form above.
|
||||
|
||||
Reference in New Issue
Block a user