zcatgui/docs/MOBILE_WEB_BACKENDS.md
reugenio e0d7e99bb6 fix: Corregir nombre de usuario Arno → R.Eugenio
Arno es el nombre de la carpeta/servidor, no del usuario.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-17 10:39:22 +01:00

534 lines
22 KiB
Markdown

# 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) + R.Eugenio
---
## 脥ndice
1. [Visi贸n General](#visi贸n-general)
2. [WASM Backend (Navegador)](#wasm-backend-navegador)
3. [Android Backend](#android-backend)
4. [iOS Backend](#ios-backend)
5. [Arquitectura Com煤n](#arquitectura-com煤n)
6. [Decisiones de Dise帽o](#decisiones-de-dise帽o)
7. [Troubleshooting](#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`:
```zig
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
```bash
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)
```zig
// 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)
```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:
```bash
zig build wasm
```
2. Servir el directorio `web/`:
```bash
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
```zig
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
```bash
# 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
```zig
// 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:
```bash
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:
```xml
<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
```bash
# 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
```c
// 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:
```bash
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:
```objc
#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:
```zig
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
- [Zig Cross-Compilation](https://zig.guide/build-system/cross-compilation/)
- [ZigAndroidTemplate](https://github.com/ikskuh/ZigAndroidTemplate)
- [Zig iOS Example](https://github.com/kubkon/zig-ios-example)
- [WebAssembly with Zig](https://ziglang.org/documentation/master/#WebAssembly)
- [ANativeActivity](https://developer.android.com/ndk/reference/struct/a-native-activity)
- [UIKit](https://developer.apple.com/documentation/uikit)