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>
534 lines
22 KiB
Markdown
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) + Arno
|
|
|
|
---
|
|
|
|
## 脥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)
|