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>
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
- Visi贸n General
- WASM Backend (Navegador)
- Android Backend
- iOS Backend
- Arquitectura Com煤n
- Decisiones de Dise帽o
- 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
-
Compilar:
zig build wasm -
Servir el directorio
web/:cd web python3 -m http.server 8080 # o cualquier servidor HTTP est谩tico -
Abrir
http://localhost:8080en 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_HOMEconfigurada (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
-
Compilar la shared library:
zig build android -
Copiar
android/libs/arm64-v8a/libzcatgui.soa tu proyecto:app/src/main/jniLibs/arm64-v8a/libzcatgui.so -
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
-
Compilar la static library:
zig build ios # Para dispositivo zig build ios-sim # Para simulador -
En Xcode:
- A帽adir
libzcatgui.aa "Link Binary With Libraries" - A帽adir
ios/ZcatguiBridge.hyios/ZcatguiBridge.mal proyecto - Crear un
UIViewControllerque useZcatguiViewController
- A帽adir
-
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?
- Compatibilidad universal: Funciona en cualquier dispositivo
- Sin dependencias GPU: No necesita OpenGL/Vulkan/Metal
- Predictibilidad: Mismo resultado en todas las plataformas
- 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:
- Sin dependencia de headers: No necesitas el SDK instalado para compilar el c贸digo Zig base
- Control preciso: Declaramos solo lo que usamos
- 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.soest谩 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.mal target de compilaci贸n - Verifica que el bridge header est谩 incluido