zcatgui/docs/MOBILE_WEB_BACKENDS.md
reugenio 6889474327 feat: zcatgui v0.15.0 - Mobile & Web Backends
WASM Backend:
- src/backend/wasm.zig: Browser backend using extern JS functions
- web/zcatgui.js: Canvas 2D rendering bridge (~200 LOC)
- web/index.html: Demo page with event handling
- examples/wasm_demo.zig: Widget showcase for browser
- Output: 18KB WASM binary

Android Backend:
- src/backend/android.zig: ANativeActivity + ANativeWindow
- examples/android_demo.zig: Touch-enabled demo
- Touch-to-mouse event mapping
- Logging via __android_log_print
- Targets: ARM64 (device), x86_64 (emulator)

iOS Backend:
- src/backend/ios.zig: UIKit bridge via extern C functions
- ios/ZcatguiBridge.h: Objective-C header
- ios/ZcatguiBridge.m: UIKit implementation (~320 LOC)
- CADisplayLink render loop
- Touch event queue with @synchronized
- Targets: ARM64 (device), ARM64 simulator

Build System:
- WASM: zig build wasm
- Android: zig build android / android-x86
- iOS: zig build ios / ios-sim
- Conditional compilation for platform detection

Documentation:
- docs/MOBILE_WEB_BACKENDS.md: Comprehensive guide (~400 lines)
- Updated DEVELOPMENT_PLAN.md with FASE 10
- Updated CLAUDE.md with new commands

Stats: 3 backends, ~1500 new LOC, cross-platform ready

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-09 18:20:13 +01:00

22 KiB

zcatgui - Mobile & Web Backends

Documentaci贸n completa de los backends para WASM (navegador), Android e iOS.

Fecha: 2025-12-09 Versi贸n: v0.15.0 Autor: Claude (Opus 4.5) + Arno


脥ndice

  1. Visi贸n General
  2. WASM Backend (Navegador)
  3. Android Backend
  4. iOS Backend
  5. Arquitectura Com煤n
  6. Decisiones de Dise帽o
  7. Troubleshooting

Visi贸n General

zcatgui soporta m煤ltiples plataformas a trav茅s de backends intercambiables:

Backend Plataforma Estado Build Command
SDL2 Desktop (Linux/Win/Mac) 鉁? Completo zig build
WASM Navegadores web 鉁? Completo zig build wasm
Android Android 5.0+ 鉁? Completo* zig build android
iOS iOS 13.0+ 鉁? Completo* zig build ios

*Requiere SDK/NDK de la plataforma para compilar.

Principio de Dise帽o

Todos los backends implementan la misma interfaz Backend.VTable:

pub const VTable = struct {
    pollEvent: *const fn (ptr: *anyopaque) ?Event,
    present: *const fn (ptr: *anyopaque, fb: *const Framebuffer) void,
    getSize: *const fn (ptr: *anyopaque) SizeResult,
    deinit: *const fn (ptr: *anyopaque) void,
};

Esto permite que el c贸digo de la aplicaci贸n sea id茅ntico en todas las plataformas.


WASM Backend (Navegador)

Archivos

src/backend/wasm.zig      # Backend Zig (extern functions, event parsing)
web/zcatgui.js            # Glue code JavaScript (Canvas API, eventos)
web/index.html            # Demo HTML
examples/wasm_demo.zig    # Aplicaci贸n demo

Compilaci贸n

zig build wasm
# Genera: web/zcatgui-demo.wasm (aproximadamente 18KB)

C贸mo funciona

鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?
鈹?                    Arquitectura WASM                      鈹?
鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?
鈹?                                                            鈹?
鈹?   鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?      鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?       鈹?
鈹?   鈹?  JavaScript    鈹?      鈹?     WASM       鈹?       鈹?
鈹?   鈹?  (zcatgui.js)  鈹?      鈹?   (Zig code)   鈹?       鈹?
鈹?   鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?      鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?       鈹?
鈹?   鈹? Canvas 2D API  鈹? 鈫? 鈹? js_canvas_*   鈹?       鈹?
鈹?   鈹? Event Queue    鈹? 鈫? 鈹? js_poll_event 鈹?       鈹?
鈹?   鈹? Timing         鈹? 鈫? 鈹? js_get_time   鈹?       鈹?
鈹?   鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?      鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?       鈹?
鈹?                                                            鈹?
鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?

Funciones Extern (Zig 鈫? JS)

// En wasm.zig - declaradas como extern "env"
extern "env" fn js_canvas_init(width: u32, height: u32) void;
extern "env" fn js_canvas_present(pixels: [*]const u32, width: u32, height: u32) void;
extern "env" fn js_get_canvas_width() u32;
extern "env" fn js_get_canvas_height() u32;
extern "env" fn js_console_log(ptr: [*]const u8, len: usize) void;
extern "env" fn js_get_time_ms() u64;
extern "env" fn js_poll_event(event_buffer: [*]u8) u32;

Funciones Export (JS 鈫? Zig)

// La aplicaci贸n WASM exporta estas funciones
export fn wasm_main() void;   // Llamada al inicio
export fn wasm_frame() void;  // Llamada cada frame (requestAnimationFrame)

Formato de Eventos

Tipo C贸digo Formato del Buffer
None 0 -
KeyDown 1 [keyCode: u8, modifiers: u8]
KeyUp 2 [keyCode: u8, modifiers: u8]
MouseMove 3 [x: i32, y: i32]
MouseDown 4 [x: i32, y: i32, button: u8]
MouseUp 5 [x: i32, y: i32, button: u8]
Wheel 6 [x: i32, y: i32, deltaX: i32, deltaY: i32]
Resize 7 [width: u32, height: u32]
Quit 8 -
TextInput 9 [len: u8, text: up to 31 bytes]

Formato de P铆xeles

El framebuffer usa u32 en formato RGBA (little-endian):

  • Byte 0: Red
  • Byte 1: Green
  • Byte 2: Blue
  • Byte 3: Alpha

El JavaScript convierte esto a ImageData para Canvas 2D.

Uso

  1. Compilar:

    zig build wasm
    
  2. Servir el directorio web/:

    cd web
    python3 -m http.server 8080
    # o cualquier servidor HTTP est谩tico
    
  3. Abrir http://localhost:8080 en el navegador

Ejemplo de Aplicaci贸n WASM

const std = @import("std");
const zcatgui = @import("zcatgui");

const allocator = std.heap.wasm_allocator;
var ctx: ?*zcatgui.Context = null;

export fn wasm_main() void {
    // Inicializar backend y context
    const be = allocator.create(zcatgui.backend.wasm.WasmBackend) catch return;
    be.* = zcatgui.backend.wasm.WasmBackend.init(800, 600) catch return;

    const c = allocator.create(zcatgui.Context) catch return;
    c.* = zcatgui.Context.init(allocator, 800, 600) catch return;
    ctx = c;
}

export fn wasm_frame() void {
    const c = ctx orelse return;

    // Procesar eventos, dibujar UI, renderizar...
    c.beginFrame();
    zcatgui.label(c, "Hello from WASM!");
    c.endFrame();

    // Renderizar a framebuffer y presentar
    var fb = zcatgui.render.Framebuffer.init(allocator, 800, 600) catch return;
    defer fb.deinit();
    // ... render y present
}

Android Backend

Archivos

src/backend/android.zig       # Backend Zig (ANativeActivity, input, window)
examples/android_demo.zig     # Aplicaci贸n demo

Compilaci贸n

# ARM64 (dispositivos reales)
zig build android
# Genera: android/libs/arm64-v8a/libzcatgui.so

# x86_64 (emulador)
zig build android-x86
# Genera: android/libs/x86_64/libzcatgui.so

Requisitos

  • Android NDK instalado
  • Variable ANDROID_NDK_HOME configurada (opcional, Zig puede detectarlo)

C贸mo funciona

鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?
鈹?               Arquitectura Android                    鈹?
鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?
鈹?                                                        鈹?
鈹?   鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?       鈹?
鈹?   鈹?          Android System                   鈹?       鈹?
鈹?   鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?       鈹?
鈹?   鈹? ANativeActivity     鈹? ANativeWindow     鈹?       鈹?
鈹?   鈹? (lifecycle)         鈹? (surface/pixels)  鈹?       鈹?
鈹?   鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?       鈹?
鈹?            鈹?                      鈹?                   鈹?
鈹?            鈻?                      鈻?                   鈹?
鈹?   鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?       鈹?
鈹?   鈹?   android.zig (Zig backend)                鈹?       鈹?
鈹?   鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?       鈹?
鈹?   鈹? - Touch 鈫? Mouse events                    鈹?       鈹?
鈹?   鈹? - Keys 鈫? Key events                       鈹?       鈹?
鈹?   鈹? - ANativeWindow_lock() 鈫? direct pixels   鈹?       鈹?
鈹?   鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?       鈹?
鈹?                                                        鈹?
鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?

APIs de Android usadas

// Declaradas como extern "android" en android.zig
extern "android" fn ANativeWindow_getWidth(window: *ANativeWindow) i32;
extern "android" fn ANativeWindow_getHeight(window: *ANativeWindow) i32;
extern "android" fn ANativeWindow_lock(...) i32;
extern "android" fn ANativeWindow_unlockAndPost(...) i32;
extern "android" fn ALooper_forThread() ?*ALooper;
extern "android" fn AInputQueue_*(...);  // Manejo de input
extern "android" fn AInputEvent_*(...);  // Parsing de eventos
extern "log" fn __android_log_write(...);  // Logging

Mapeo de Eventos

Android Event zcatgui Event
AMOTION_EVENT_ACTION_DOWN mouse.pressed = true, button = .left
AMOTION_EVENT_ACTION_UP mouse.pressed = false, button = .left
AMOTION_EVENT_ACTION_MOVE mouse move
AKEY_EVENT_ACTION_DOWN key.pressed = true
AKEY_EVENT_ACTION_UP key.pressed = false
AKEYCODE_BACK (release) quit event

Integraci贸n en Proyecto Android

  1. Compilar la shared library:

    zig build android
    
  2. Copiar android/libs/arm64-v8a/libzcatgui.so a tu proyecto:

    app/src/main/jniLibs/arm64-v8a/libzcatgui.so
    
  3. En AndroidManifest.xml, usar NativeActivity:

    <activity android:name="android.app.NativeActivity"
              android:label="zcatgui App">
        <meta-data android:name="android.app.lib_name"
                   android:value="zcatgui"/>
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    

iOS Backend

Archivos

src/backend/ios.zig           # Backend Zig (extern C functions)
ios/ZcatguiBridge.h           # Header Objective-C
ios/ZcatguiBridge.m           # Implementaci贸n Objective-C (UIKit)

Compilaci贸n

# Dispositivo real (ARM64)
zig build ios
# Genera: ios/libzcatgui.a

# Simulador (ARM64 Apple Silicon)
zig build ios-sim
# Genera: ios/libzcatgui-simulator.a

Requisitos

  • macOS con Xcode instalado
  • Para dispositivo real: certificado de desarrollador Apple

C贸mo funciona

鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?
鈹?                 Arquitectura iOS                      鈹?
鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?
鈹?                                                        鈹?
鈹?   鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?      鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?       鈹?
鈹?   鈹? Objective-C   鈹?      鈹?  Zig Static   鈹?       鈹?
鈹?   鈹? Bridge        鈹? 鈫斺啌鈫? 鈹?  Library      鈹?       鈹?
鈹?   鈹? (ZcatguiBridge)鈹?      鈹?  (ios.zig)    鈹?       鈹?
鈹?   鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?      鈹溾攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹も攢鈹?       鈹?
鈹?   鈹? ZcatguiView   鈹?      鈹?                鈹?       鈹?
鈹?   鈹? (UIView)      鈹?      鈹? ios_view_*()  鈹?       鈹?
鈹?   鈹? - Touch       鈹? 鈫? 鈹? ios_poll_*()  鈹?       鈹?
鈹?   鈹? - Render      鈹? 鈫? 鈹? ios_log()     鈹?       鈹?
鈹?   鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?      鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?       鈹?
鈹?          鈹?                                            鈹?
鈹?          鈻?                                            鈹?
鈹?   鈹屸攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹愨攢鈹?                                  鈹?
鈹?   鈹? UIKit/CoreG.  鈹?                                  鈹?
鈹?   鈹? CADisplayLink 鈹?                                  鈹?
鈹?   鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?                                  鈹?
鈹?                                                        鈹?
鈹斺攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹粹攢鈹?

Funciones del Bridge

// Declaradas en ZcatguiBridge.h, implementadas en ZcatguiBridge.m
// Llamadas desde ios.zig via extern "c"

void ios_view_init(uint32_t width, uint32_t height);
uint32_t ios_view_get_width(void);
uint32_t ios_view_get_height(void);
void ios_view_present(const uint32_t *pixels, uint32_t width, uint32_t height);
uint32_t ios_poll_event(uint8_t *buffer);
void ios_log(const uint8_t *ptr, size_t len);
uint64_t ios_get_time_ms(void);

Formato de Eventos iOS

Tipo C贸digo Formato del Buffer
None 0 -
TouchDown 1 [x: i32, y: i32]
TouchUp 2 [x: i32, y: i32]
TouchMove 3 [x: i32, y: i32]
KeyDown 4 [keyCode: u8, modifiers: u8]
KeyUp 5 [keyCode: u8, modifiers: u8]
Resize 6 [width: u32, height: u32]
Quit 7 -

Integraci贸n en Proyecto Xcode

  1. Compilar la static library:

    zig build ios      # Para dispositivo
    zig build ios-sim  # Para simulador
    
  2. En Xcode:

    • A帽adir libzcatgui.a a "Link Binary With Libraries"
    • A帽adir ios/ZcatguiBridge.h y ios/ZcatguiBridge.m al proyecto
    • Crear un UIViewController que use ZcatguiViewController
  3. Ejemplo de ViewController:

    #import "ZcatguiBridge.h"
    
    @interface MyViewController : ZcatguiViewController
    @end
    
    @implementation MyViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        zcatgui_ios_init(self.view.bounds.size.width,
                         self.view.bounds.size.height);
        [self startRenderLoop];
    }
    
    - (void)renderFrame:(CADisplayLink *)displayLink {
        // Llamar a tu funci贸n de frame Zig
        zcatgui_ios_frame();
    }
    
    @end
    

Arquitectura Com煤n

Compilaci贸n Condicional

En src/zcatgui.zig, los backends se importan condicionalmente:

const builtin = @import("builtin");

pub const backend = struct {
    // SDL2 solo en desktop (no WASM, no Android)
    pub const Sdl2Backend = if (builtin.cpu.arch == .wasm32 or
                                builtin.cpu.arch == .wasm64 or
                                (builtin.os.tag == .linux and builtin.abi == .android))
        void
    else
        @import("backend/sdl2.zig").Sdl2Backend;

    // WASM solo en WASM
    pub const wasm = if (builtin.cpu.arch == .wasm32 or builtin.cpu.arch == .wasm64)
        @import("backend/wasm.zig")
    else
        struct { pub const WasmBackend = void; /* stubs */ };

    // Android solo en Android
    pub const android = if (builtin.os.tag == .linux and builtin.abi == .android)
        @import("backend/android.zig")
    else
        struct { pub const AndroidBackend = void; /* stubs */ };

    // iOS solo en iOS
    pub const ios = if (builtin.os.tag == .ios)
        @import("backend/ios.zig")
    else
        struct { pub const IosBackend = void; /* stubs */ };
};

Build Targets

En build.zig:

Target CPU Arch OS ABI
Desktop native native native
WASM wasm32 freestanding -
Android ARM64 aarch64 linux android
Android x86_64 x86_64 linux android
iOS Device aarch64 ios -
iOS Simulator aarch64 ios simulator

Decisiones de Dise帽o

驴Por qu茅 Software Rendering?

  1. Compatibilidad universal: Funciona en cualquier dispositivo
  2. Sin dependencias GPU: No necesita OpenGL/Vulkan/Metal
  3. Predictibilidad: Mismo resultado en todas las plataformas
  4. Debugging simple: Es solo un array de p铆xeles

驴Por qu茅 extern declarations en lugar de @cImport?

Para Android e iOS, usamos declaraciones extern manuales en lugar de @cImport:

  1. Sin dependencia de headers: No necesitas el SDK instalado para compilar el c贸digo Zig base
  2. Control preciso: Declaramos solo lo que usamos
  3. Portabilidad: El mismo c贸digo funciona en cualquier m谩quina

驴Por qu茅 touch se mapea a mouse?

Simplifica el c贸digo de la aplicaci贸n:

  • Touch down = Mouse left button down
  • Touch up = Mouse left button up
  • Touch move = Mouse move

Para gestos avanzados (pinch, swipe), el sistema de gestos de zcatgui maneja la traducci贸n.


Troubleshooting

WASM

Error: "Canvas not found"

  • Aseg煤rate de que el canvas tiene id="zcatgui-canvas" en el HTML

Error: "Memory access out of bounds"

  • Verifica que el framebuffer tiene el tama帽o correcto
  • Aseg煤rate de usar std.heap.wasm_allocator

Android

Error: "unable to find dynamic system library 'android'"

  • El Android NDK no est谩 instalado o no est谩 en el PATH
  • Instala el NDK: sdkmanager "ndk;25.2.9519653"

App crashes on startup

  • Verifica que libzcatgui.so est谩 en la carpeta correcta de jniLibs
  • Verifica que el nombre en AndroidManifest coincide

iOS

Error: "Undefined symbols for architecture arm64"

  • Aseg煤rate de linkear libzcatgui.a
  • Verifica que est谩s usando el .a correcto (device vs simulator)

Bridge functions not found

  • A帽ade ZcatguiBridge.m al target de compilaci贸n
  • Verifica que el bridge header est谩 incluido

Referencias