diff --git a/current/CHECKPOINT-FFI.md b/current/CHECKPOINT-FFI.md index fc83681..94557b6 100644 --- a/current/CHECKPOINT-FFI.md +++ b/current/CHECKPOINT-FFI.md @@ -600,27 +600,46 @@ matching the expected output. Phase 3.2 C4 landed: UIKit chrome cluster migrated. Six classes declared (UIScreen, UIView, UIWindow, UIViewController, UITextField -— plus the existing C1/C2/C3 classes already in place). Migration -sites: `show_keyboard` / `hide_keyboard` use `tf.becomeFirstResponder()` -/ `tf.resignFirstResponder()`; `uikit_refresh_safe_insets` uses -`gl_view.safeAreaInsets()`; `uikit_read_screen_scale` and the GL- -context bring-up both use `UIScreen.mainScreen().nativeScale()`; -keyboard-frame callback uses `win.screen().bounds()`; the scene- -connect bring-up chains `UIWindow.alloc().initWithWindowScene(scene)` -and `UIViewController.alloc().init()` then `vc.setView(...)`, -`win.setRootViewController(...)`, `gl_view.layer()`, -`UITextField.alloc().init()`, `gl_view.addSubview(...)`, -`win.makeKeyAndVisible()`. Three `objc_getClass(...)` calls (UIWindow, -UIViewController, UITextField) are gone — the class slots come from -the declarative bindings via `__sx_objc_class_init`. C4 is the -cluster that triggered issue-0043; with the fix in, the chained -dispatch resolves correctly under lazy lowering. 167/167 tests + -chess clean on macOS / iOS sim / Android. +— plus the existing C1/C2/C3 classes already in place). Three +`objc_getClass(...)` calls (UIWindow, UIViewController, UITextField) +are gone — the class slots come from the declarative bindings via +`__sx_objc_class_init`. C4 is the cluster that triggered +issue-0043; with the fix in, the chained dispatch resolves +correctly under lazy lowering. + +Phase 3.2 C5 landed: view tree + GL drawables cluster migrated. +CALayer (`setOpaque`), CAEAGLLayer (`setDrawableProperties`), and +EAGLContext (`alloc`, `initWithAPI`, `setCurrentContext`, +`renderbufferStorage_fromDrawable`, `presentRenderbuffer`) declared. +UIView gained `setContentScaleFactor` and `layer` now returns +`*CALayer` (was opaque `*void`). Migration sites: +`uikit_create_gl_context` uses `EAGLContext.alloc().initWithAPI(...)` +then `EAGLContext.setCurrentContext(ctx)`; +`uikit_setup_renderbuffer` uses +`gl_ctx.renderbufferStorage_fromDrawable(...)`; +`uikit_present_renderbuffer` uses `gl_ctx.presentRenderbuffer(...)`; +the scene-connect bring-up uses `gl_layer.setOpaque(1)`, +`eagl_layer.setDrawableProperties(...)`, and +`gl_view.setContentScaleFactor(scale)`. One more `objc_getClass` +(EAGLContext) gone. 167/167 + chess clean on macOS / iOS sim / +Android. + +**Phase 3.2 complete.** Surface summary: + +- `#selector("explicit:")` override (parts A1+A2). +- Locked-in golden mangling-table test (part B). +- Five uikit.sx clusters migrated to declarative `#objc_class` + (parts C1..C5) — 8 foreign Cocoa classes declared, 30+ + `#objc_call` call sites rewritten to `recv.method(args)` / + `Cls.method(args)` form. 6 redundant `objc_getClass(...)` lookups + retired. Sx-defined classes (SxAppDelegate, SxSceneDelegate, + SxGLView, SxMetalView) and a handful of foreign sites that + exercise less common paths (e.g. `objc_call(void)(delegate, + "setWindow:", ...)` from UIWindowSceneDelegate protocol) stay on + the explicit `#objc_call` form pending Phase 3.7's class-synthesis + work. Open work: -- **Phase 3 step 3.2 — C5** — uikit.sx migration (view tree + GL - drawables: CAEAGLLayer, EAGLContext, plus any remaining - CAMetalLayer / NSTimer sites). - **Phase 3 step 3.3** — `property name: Type` synthesizes `inst.name` → `[inst name]` getter and `inst.name = x` → `[inst setName: x]` setter. `#setter("...")` overrides the setter diff --git a/library/modules/platform/uikit.sx b/library/modules/platform/uikit.sx index 53337c8..846603e 100644 --- a/library/modules/platform/uikit.sx +++ b/library/modules/platform/uikit.sx @@ -113,6 +113,25 @@ CADisplayLink :: #foreign #objc_class("CADisplayLink") { duration :: (self: *Self) -> f64; } +// ── View tree + GL drawables (Phase 3.2 C5) ──────────────────────────── +// (Declared before UIView so `layer :: (...) -> *CALayer` can reference it.) + +CALayer :: #foreign #objc_class("CALayer") { + setOpaque :: (self: *Self, opaque: s8); +} + +CAEAGLLayer :: #foreign #objc_class("CAEAGLLayer") { + setDrawableProperties :: (self: *Self, props: *void); +} + +EAGLContext :: #foreign #objc_class("EAGLContext") { + alloc :: () -> *EAGLContext; + initWithAPI :: (self: *Self, api: s32) -> *EAGLContext; + setCurrentContext :: (ctx: *EAGLContext); + renderbufferStorage_fromDrawable :: (self: *Self, target: u32, drawable: *void) -> s8; + presentRenderbuffer :: (self: *Self, target: u32) -> s8; +} + // ── UIKit chrome (Phase 3.2 C4) ──────────────────────────────────────── UIScreen :: #foreign #objc_class("UIScreen") { @@ -122,11 +141,10 @@ UIScreen :: #foreign #objc_class("UIScreen") { } UIView :: #foreign #objc_class("UIView") { - safeAreaInsets :: (self: *Self) -> UIEdgeInsets; - addSubview :: (self: *Self, view: *void); - // `-layer` returns a CALayer*; declared as opaque pointer for now - // (CALayer's own declarative binding is in the C5 cluster). - layer :: (self: *Self) -> *void; + safeAreaInsets :: (self: *Self) -> UIEdgeInsets; + addSubview :: (self: *Self, view: *void); + layer :: (self: *Self) -> *CALayer; + setContentScaleFactor :: (self: *Self, scale: f64); } UIWindow :: #foreign #objc_class("UIWindow") { @@ -526,17 +544,14 @@ uikit_keyboard_will_change_frame :: (self: *void, _cmd: *void, notification: *vo uikit_create_gl_context :: (plat: *UIKitPlatform) { inline if OS != .ios { return; } - EAGLContext := objc_getClass("EAGLContext".ptr); - // UIScreen class slot comes from the declarative #objc_class binding. - // Read the screen scale up-front so callers can size font caches and // textures with the right DPI before the window even exists. screen := UIScreen.mainScreen(); plat.dpi_scale = xx screen.nativeScale(); - ctx_raw := #objc_call(*void)(EAGLContext, "alloc"); - plat.gl_ctx = #objc_call(*void)(ctx_raw, "initWithAPI:", EAGL_API_GLES3); - #objc_call(void)(EAGLContext, "setCurrentContext:", plat.gl_ctx); + ctx := EAGLContext.alloc().initWithAPI(EAGL_API_GLES3); + plat.gl_ctx = xx ctx; + EAGLContext.setCurrentContext(ctx); load_gl(@ios_gl_proc); } @@ -611,12 +626,13 @@ uikit_scene_will_connect_ios :: (delegate: *void, scene: *void) { win.setRootViewController(plat.root_vc); gl_view : *UIView = xx plat.gl_view; - plat.gl_layer = gl_view.layer(); + gl_layer := gl_view.layer(); + plat.gl_layer = xx gl_layer; // Mark the layer opaque (no compositor blend). Required for EAGL + // recommended for Metal (CAMetalLayer.opaque defaults to YES but doesn't // hurt to be explicit). - #objc_call(void)(plat.gl_layer, "setOpaque:", xx 1); + gl_layer.setOpaque(1); if plat.gpu_mode == .gles { // EAGL drawable properties dict required by @@ -634,7 +650,8 @@ uikit_scene_will_connect_ios :: (delegate: *void, scene: *void) { dict := NSMutableDictionary.dictionary(); dict.setObject_forKey(xx ns_no, retained_key); dict.setObject_forKey(rgba8_value, colorformat_key); - #objc_call(void)(plat.gl_layer, "setDrawableProperties:", xx dict); + eagl_layer : *CAEAGLLayer = xx gl_layer; + eagl_layer.setDrawableProperties(xx dict); } // EAGLContext + load_gl were already done in uikit_create_gl_context() @@ -647,7 +664,7 @@ uikit_scene_will_connect_ios :: (delegate: *void, scene: *void) { screen2 := win.screen(); scale := screen2.nativeScale(); plat.dpi_scale = xx scale; - #objc_call(void)(plat.gl_view, "setContentScaleFactor:", scale); + gl_view.setContentScaleFactor(scale); // Renderbuffer is allocated lazily in -[SxGLView layoutSubviews] once // the layer has its real on-screen bounds. makeKeyAndVisible triggers @@ -691,7 +708,8 @@ uikit_setup_renderbuffer :: (plat: *UIKitPlatform) { glBindRenderbuffer(GL_RENDERBUFFER, plat.color_renderbuffer); - #objc_call(bool)(plat.gl_ctx, "renderbufferStorage:fromDrawable:", GL_RENDERBUFFER, plat.gl_layer); + gl_ctx : *EAGLContext = xx plat.gl_ctx; + gl_ctx.renderbufferStorage_fromDrawable(GL_RENDERBUFFER, plat.gl_layer); glBindFramebuffer(GL_FRAMEBUFFER, plat.framebuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, plat.color_renderbuffer); @@ -723,7 +741,8 @@ uikit_setup_renderbuffer :: (plat: *UIKitPlatform) { uikit_present_renderbuffer :: (self: *UIKitPlatform) { inline if OS != .ios { return; } glBindRenderbuffer(GL_RENDERBUFFER, self.color_renderbuffer); - #objc_call(bool)(self.gl_ctx, "presentRenderbuffer:", GL_RENDERBUFFER); + gl_ctx : *EAGLContext = xx self.gl_ctx; + gl_ctx.presentRenderbuffer(GL_RENDERBUFFER); } // ── SxGLView class ─────────────────────────────────────────────────────────