Skip to content

feat(linker): RmlUI DOM bridge — RmlUi 6.2 + SDL3 reales (v1.7.0) - #25

Open
AndyTechnologies wants to merge 35 commits into
mainfrom
feature/rmlui-dom-bridge
Open

AndyTechnologies wants to merge 35 commits into
mainfrom
feature/rmlui-dom-bridge

Conversation

@AndyTechnologies

Copy link
Copy Markdown
Owner

Resumen

  • Template C++ de RmlUI real: compila, linkea y corre contra RmlUi 6.2 + SDL3 3.2.4 (antes solo se renderizaba en tests).
  • Los 3 ejemplos (rmlui-basic, rmlui-dom-api, rmlui-rust) generan binarios nativos con ventana SDL3 + GL3 y corren limpios.
  • Smoke E2E en CI: Linux con Xvfb + llvmpipe, macOS con ventana cocoa; Windows documentado (sin ICD GL3).

Cambios

Archivo Cambio
packages/linker/templates-rmlui/*.c.njk API RmlUi 6.2 (SetInnerRML, InstanceElement #text, GetNumDocuments/GetDocument, LoadFontFace 6 args), SDL3 event API, SetViewport, fonts absolutas, entry una sola vez
packages/linker/src/rmlui-plugin.ts getRmluiConfig (templatePath), _readAsString (UCS2), bodies custom QuerySelectorAll/FreeNodeList, extraLibs con backends SDL/GL3 + orden de libs + freetype
packages/linker/src/compiler.ts copia rmlui-abi.h al build, add_compile_definitions, fuentes extra en CMake
packages/linker/src/rmlui-setup.ts fallback a source-build de SDL3 en 404 + checksum
packages/types/src/rmlui-abi.h / bindings ABI canónico 6.2
examples/rmlui-* RCSS 6.2 (sin border shorthand), href relativo al documento, wapp.json con plugin
scripts/rmlui-smoke.mjs smoke E2E: corre binarios ~4s, valida stderr
.github/workflows/ci.yml xvfb + steps de smoke rmlui por SO
docs/ plugin rmlui, caché de deps, cobertura por SO

Test Plan

  • pnpm vitest run → 459 passed (43 files)
  • pnpm -r build verde
  • node scripts/test-examples.mjs → 3 ejemplos rmlui build+link
  • node scripts/rmlui-smoke.mjs → 3/3 PASS local
  • xvfb-run -a node scripts/rmlui-smoke.mjs sin display → 3/3 PASS (CI Linux)
  • CI macOS (primer run en este PR)

Nota

La rama feature/rmlui-dom-bridge acumula S1–S5 del cambio SDD rmlui-bridge (release v1.7.0): pins 6.2, migración ABI, bindings, descarga real con checksum y ahora el template funcional end-to-end. No hay issue linkeado: el repo no usa issues para este flujo.

AndyTechnologies and others added 28 commits July 25, 2026 20:36
…strategy -> generateCCode -> renderTemplate)
- rmlui-abi.h: extern "C" declarations for all 44 ABI functions
  with opaque handles (Rml_ContextId, Rml_ElementId, etc.) and
  error enum (Rml_Error)
- rmlui.hh: RAII wrappers RmlContext, RmlElement, and free
  functions over the C ABI; includes callback registry for
  std::function-based event listeners

C ABI covers: context lifecycle, document loading, element tree
construction, attributes and content, style properties, event
system, class list, font/texture loading, render loop, query
selectors, document body/head access, and debugger toggle.
Template restructuring:
- Create _rmlui-state.c.njk: file-scope shared state (element map,
  callback registry, context registry, SDL/GL variables) plus all
  44 extern "C" ABI function implementations with _writeString
  WASM string writer
- Fix setup include order: move _rmlui-setup into main() scope
  before host function definitions
- Update _rmlui-event-loop, _rmlui-render, _rmlui-cleanup to use
  file-scope statics via C ABI calls

Plugin restructuring:
- Replace all placeholder host function bodies with real C++ code
  that bridges WASM calls to the file-scope C ABI implementations
- Add helpers for common patterns: scalarI32I32, string1I32,
  handleStringI32, handleStringStringReturn, etc.
- Register all 44 host functions from the ABI spec
- Binary data functions (Rml_LoadFontFromBuffer,
  Rml_LoadTextureFromBuffer) read WASM memory directly
… template

Adds extern C function bodies to _rmlui-state.c.njk for:
Rml_LoadDocumentFromBuffer, Rml_QuerySelectorAll, Rml_FreeNodeList,
Rml_GetTextureDimensions, Rml_SetResourcePath, Rml_RegisterResourceProvider

Also fixes Rml_SetResourcePath to not reference undeclared variable.
…plugin

W3: SDL_GL_MakeCurrent in init sequence (main.c.njk)
W4: Reentrancy guard in event dispatch (_rmlui-state.c.njk)
W5: Separate RmlUI_Update() from ProcessSdlEvents (main.c.njk + _rmlui-state.c.njk)
W6: RmlStyle RAII class in rmlui.hh (keeps style methods on RmlElement)
W7: Element + Document class with browser-like DOM API in AS bindings
W8: Default font configurable via rmlui.resources.defaultFont
W9: Texture loading stubs improved (WASI-aware documentation)
W10: Elements survive removeChild for re-append to different parent
S1: Download URLs with proper source-build fallback handling
S2: Rust crate structure with build.rs + bindgen scaffold
S3: _embedded-resources.c.njk template for embedded resource arrays
S4: querySelectorAll in Element class + raw FFI imports
S5: WASM function table dispatch documentation in callback system
- MountEntry interface: host path + guest WASI virtual path
- PermissionDecision enum: AllowOnce, AllowForever, Deny
- mounts field in NativeAppOptions and WappConfig
- fs-runtime.h: header-only C++ runtime for filesystem access control
  (SHA-256 permission IDs, isPathAllowed, requestPath, promptUser)
- compileCpp() copies fs-runtime.h to build dir before compilation
- generateCCode() accepts optional mounts parameter
- Template main.c.njk: unconditional fs-runtime.h include,
  preopen_dir and _fs_allowed_roots from mounts config
- Updated golden files to include fs-runtime.h header
- Codegen tests: SHA-256 test vectors, mount validation
… linker

- BuildManifestOptions: optional mountsHash field
- isBuildUpToDate: returns false when mountsHash differs
- saveBuildManifest: persists mountsHash in manifest
- NativeAppBuilder.setMounts() with computeMountsHash()
- createNativeApp() passes mounts to generateCCode and build cache
- Tests: mountsHash mismatch/match/save scenarios
…dd integration tests

- builtin-host-functions: register 'request-path' env import generator
  that calls FsRuntime::requestPath with _fs_allowed_roots
- host-function-registry.test: verify request-path C++ body generation
- CLI: reads config.mounts from wapp.json into NativeAppOptions
- filesystem-access.integration.test: full pipeline integration tests
  (codegen + cache + mounts)
- Move working change spec/design/tasks to archive/2026-07-25-filesystem-access/
- Add verify-report.md (8/8 checks, 373 tests)
- Copy finalized specs to openspec/specs/ (static-mounts,
  permission-manager, dynamic-fs-access)
Template renderer tests (8 new):
- Renders interactive RmlUI loop with MakeCurrent (W3)
- Excludes RmlUI code when disabled
- Respects debugger flag
- Consumes configured defaultFont (W8)
- Includes all 51+ C ABI functions in generated code
- W10: elements survive removeChild (no erase)
- S3: embedded resource accessor present
- W4: reentrancy guard in event dispatch

Examples (3 new files + 3 updated):
- rmlui-basic: rewritten to use Element/Document classes
- rmlui-dom-api: comprehensive example with all DOM features
- rmlui-rust: ui/ assets and README

Also:
- Copied _preamble.c.njk to templates-rmlui for template isolation
- Fixed template-context.ts type to include defaultFont
# Conflicts:
#	.github/workflows/release.yml
#	examples/precompiled/src/main.wasm
#	packages/linker/src/build-cache.ts
#	packages/linker/src/codegen.ts
#	packages/linker/src/index.ts
#	packages/linker/src/template-context.ts
#	packages/linker/templates/main.c.njk
#	packages/types/src/index.ts
…funcs)

- ABI: LoadDocumentFromString → LoadDocumentFromMemory(ctx, rml, url),
  +GetNumDocuments/GetDocument(index), clase class_list → SetClass/
  IsClassSet/SetClassNames, docs de ownership AppendChild/RemoveChild
- rmlui.hh: sync RAII con el ABI migrado (setClass/isClassSet/
  setClassNames, getDocument(index)/getNumDocuments, loadDocumentFromMemory;
  addClass/removeClass/toggleClass/hasClass como wrappers de conveniencia)
- Bindings regenerados con bindgen (52 funciones): Rust FFI y
  AssemblyScript; clases Element/Document actualizadas al ABI nuevo
- rmlui-plugin.ts: +7 host functions (LoadDocumentFromMemory,
  GetNumDocuments, GetDocument, SetClass, IsClassSet, SetClassNames),
  −4 legacy −LoadDocumentFromString
- Census automatizado 4 capas: rs/ts/plugin espejo completo del ABI,
  rmlui.hh subset válido + símbolos 6.2; gate grep legacy en 0 hits
- Tests: 42/42 verdes, pnpm -r build verde
- rmlui-plugin: getRmluiConfig (templatePath propio), _readAsString para
  strings UCS2, bodies custom de QuerySelectorAll/FreeNodeList, extraLibs
  con sources de backends SDL/GL3 + defines de versión + orden de libs
  (rmlui_debugger antes que rmlui) + freetype en linux
- main.c.njk: SDL3 + defines RMLUI_SDL_VERSION_* antes de backends,
  SetViewport explícito (FBO 8cd6), fonts con ruta absoluta del cache,
  entry point una sola vez antes del loop, SystemInterface_SDL() + SetWindow
- _rmlui-state.c.njk: include rmlui-abi.h, API 6.2 (SetInnerRML/GetInnerRML,
  InstanceElement #text + ElementText::SetText, GetNumDocuments/GetDocument,
  _rmluiFindById, Style::FontStyle/FontWeight, LoadFontFace 6 args),
  reuso de contexto por nombre, helpers _rmluiQuerySelectorAllIds + _writeI32List
- compiler.ts: copia rmlui-abi.h al build, add_compile_definitions y fuentes
  extra en CMake; rmlui-setup: fallback a source-build de SDL3 en 404
- index.ts: templatePath del plugin rmlui si no viene configurado
- codegen/template-context/types: fontsDir en resources, ExtraLib.sources/defines
- ejemplos rmlui: href de RCSS relativo al documento, RCSS 6.2 sin border
  shorthand, family LatoLatin; bindings TS sin comentar @external
- tests: template-renderer-rmlui S-002/S-007/S-008 al ABI nuevo, setup/extract
  con source-build y extracción real
- .prettierignore: rmlui-bindings.ts (decoradores AS)
- scripts/rmlui-smoke.mjs: corre cada binario RmlUI ~4s y valida stderr
  (filtra logs de fonts); requiere display en Linux, directo en macOS/Windows
- test-examples.mjs: documenta skip de runtime por display (T-030)
- examples/rmlui-rust/wapp.json: habilita rmlui-plugin (antes se linkeaba
  con el template genérico, sin ventana ni loop)
- ci.yml: xvfb en deps Linux; steps de smoke tras test:integration
  (Linux: xvfb-run + llvmpipe GL3; macOS: ventana cocoa directa)
- docs/reference/config.md: sección plugins.rmlui-plugin (window,
  debugger, resources, enabled:false default)
- docs/how-to/manage-cache.md: caché de deps RmlUI (~/.wasm-linker/rmlui,
  markers, pins 6.2/3.2.4, fallback source-build)
- docs/how-to/run-integration-tests.md: smoke local + cobertura por SO
  (Windows: sin ICD GL3, solo build manual)
… plataforma-aware

- .gitattributes: eol=lf en fuentes; el checkout Windows (autocrlf) rompía el
  type stripping de Node (import .ts desde index.mjs) con SyntaxError
  (reproducido local con CRLF)
- rmlui-setup.test.ts: en win32 SDL3 usa el VC.zip (0 cmake), RmlUi hace 2;
  en linux/macOS se compila desde fuente (≥4)
- rmlui-bindgen.test.ts: fixture tar con cwd relativo (bsdtar de Windows
  interpreta '-C C:\...' como host remoto)
- rmlui-setup.test.ts: assert de --install solo en linux/macOS (win32 usa
  el VC.zip precompilado, sin cmake --install)
@AndyTechnologies AndyTechnologies self-assigned this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant