Files
FnixLib/docs/DECISIONS.md
T

5.6 KiB

Decisiones de diseño de FnixLib

Registro de las decisiones técnicas tomadas en la versión 0.1.0, con su motivo y lo que costaría revertirlas. Es un documento nuevo; no sustituye a ningún otro.

Convenciones

  • Lenguaje: C17 estricto (-std=c17, sin extensiones de GNU).
  • Nombres: funciones fnix_modulo_accion, tipos FnixTipo, constantes y macros FNIX_NOMBRE. Los identificadores van en inglés; los comentarios y los mensajes de error, en español.
  • Errores: las funciones que crean objetos devuelven NULL si fallan; las de consulta no fallan (devuelven 0/false ante argumentos inválidos). El motivo se guarda por hilo y se lee con fnix_last_error_code() / fnix_last_error(). Un éxito no borra el último error (como errno).
  • Objetos opacos: FnixWindow y FnixCanvas solo se manejan por puntero, de modo que su contenido puede cambiar sin romper la API.

Decisiones

D1. Xlib (libX11) como interfaz con el sistema gráfico de Linux

Se trata como interfaz nativa del sistema, igual que Win32 en Windows. Alternativas descartadas por ahora: hablar el protocolo X11 a mano sobre un socket (mucho trabajo sin beneficio en 0.1.0) y Wayland nativo (exige además implementar el protocolo y buscar una forma de dibujar). Los ejecutables se verifican bajo X11; en sesiones Wayland deberían funcionar mediante XWayland, pero no está verificado. Reversible: todo lo específico de X11 está en src/platform/linux/ detrás de src/platform/platform.h.

D2. Renderizador 2D por software y presentación con XPutImage

Es la forma más sencilla de validar la arquitectura sin depender de la GPU. Coste: no hay aceleración ni sincronización vertical. El backend de GPU (OpenGL) queda para la fase 4 y se añadirá detrás de la misma API de dibujo.

D3. Formato de píxel 0x00RRGGBB y requisitos de pantalla

El lienzo guarda uint32_t 0x00RRGGBB. Es lo que acepta X11 sin conversión en el caso habitual. Si el servidor no ofrece un visual TrueColor de 24/32 bits con esas máscaras y el mismo orden de bytes que la CPU, fnix_window_create falla con FNIX_ERROR_UNSUPPORTED y un mensaje explicativo (no se intenta convertir).

D4. Destino de dibujo implícito, por hilo

fnix_draw_* dibuja sobre el lienzo fijado con fnix_set_target(); fnix_begin_frame() fija el de la ventana. Mantiene la API corta (fnix_draw_circle(x, y, r, color)) y permite pruebas sin ventana usando fnix_canvas_create(). Coste: estado oculto por hilo.

D5. Ventana de tamaño fijo

Se indica con los hints de tamaño mínimo = máximo. Redimensionar exigiría decidir qué ocurre con el lienzo y no aporta a la primera versión.

D6. Entrada: estado por fotograma + cola de eventos

fnix_begin_frame() borra los pressed/released y la rueda, procesa los eventos del sistema y los aplica a una máquina de estados (input.c), que es lo que consultan fnix_key_down, fnix_key_pressed, etc. Además cada evento se guarda en una cola de 256 entradas (se descarta lo más antiguo) para quien prefiera fnix_window_poll_event. Detalles:

  • El autorepeat no vuelve a activar pressed (XkbSetDetectableAutoRepeat).
  • Al perder el foco, lo pulsado pasa a soltado: evita teclas pegadas.
  • Las teclas se identifican por el KeySym sin modificadores (índice 0) de la distribución activa; con distribuciones no QWERTY la tecla física puede cambiar de identificador. Alternativa (códigos físicos/scancodes) pospuesta.

D7. Tiempo entre fotogramas y límite de FPS

El delta time se mide de begin_frame a begin_frame (0 en el primero). El límite de FPS (60 por defecto) duerme en end_frame hasta una fecha límite que avanza un periodo por fotograma, de modo que el promedio a largo plazo es exacto. Si se va más de un fotograma tarde, se reajusta en lugar de recuperar con una ráfaga.

D8. Geometría y recorte

  • Entradas limitadas a [-2^28, 2^28]; fuera de ese rango no se dibuja y se registra un error. Con ese límite los cálculos en int64_t no desbordan.
  • Todo se recorta antes de recorrer píxeles: el coste depende del lienzo, no del tamaño de la figura (una línea de millones de píxeles fuera de pantalla es barata).
  • Cada primitiva escribe cada píxel como máximo una vez, para que la mezcla con alfa no se aplique dos veces.
  • Líneas: Bresenham con aritmética entera; los empates se redondean hacia arriba, por lo que una línea y su inversa pueden diferir en algún píxel intermedio.
  • Círculos: un píxel pertenece al disco si dx² + dy² <= r² + r; el contorno es el disco de radio r menos el de r - 1.

D9. Mezcla alfa

"Source-over" con alfa recto y redondeo al entero más cercano; alfa 255 reemplaza y alfa 0 no dibuja. fnix_clear ignora el alfa.

D10. CMake

Biblioteca estática por defecto (BUILD_SHARED_LIBS la cambia, sin verificar), tipo Release si no se indica otro, opciones FNIX_BUILD_EXAMPLES, FNIX_BUILD_TESTS, FNIX_WARNINGS_AS_ERRORS y FNIX_SANITIZE. En sistemas que no son Linux la configuración falla con un mensaje claro en vez de compilar a medias.

D11. Pruebas

Tres ejecutables sin pantalla (núcleo, dibujo, entrada) y una prueba de integración que usa un servidor X real: una segunda conexión inyecta eventos con XSendEvent y lee los píxeles de la ventana con XGetImage. Sin DISPLAY termina con código 77 y ctest la marca como omitida.

Pendiente (no implementado)

  • cmake --install, find_package(FnixLib CONFIG) y empaquetado.
  • Windows, y compilación cruzada desde Linux.
  • Imágenes y texturas, fuentes y texto, audio, matemáticas, colisiones, 3D.
  • Licencia: el repositorio no incluye LICENSE; debe elegirla el autor.