Skip to content

sjqtentacles/sml-window

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sml-window

CI

Status: IMPURE TOOL — not part of the dual-compiler purity guarantee.

The quarantined desktop-window backend for the pure sml-ui widget toolkit. This is the one place in the pure-SML GUI stack that touches the outside world: it opens a real OS window via a tiny minifb FFI shim, blits sml-ui's RGBA framebuffer into it every frame, and feeds real mouse/keyboard input back into sml-ui's pure input model — so you can actually click the checkboxes, pick the radio, drag the sliders, type in the text field, open the dropdown, switch tabs, and open/close the modal.

It mirrors the established sjqtentacles convention for impure edges (sml-readline's pure core / future driver split, sml-serve as the web stack's socket edge, sml-httpc-tool as the HTTP client's socket driver): the portable, tested, deterministic artifact is the pure toolkit; the on-screen tool is a thin, compiler-specific, unguaranteed driver.

sml-window running the live sml-ui settings window

the About modal as a z-ordered overlay

Both images are the actual framebuffer minifb displayed on screen, captured by ./bin/demo --shot (left: the GENERAL tab with the QUALITY dropdown open; right: HELP ▸ ABOUT opening the modal over a dimmed backdrop). The pixels come straight from the live sml-ui toolkit — sml-window only pumps them into the window.

What "impure / not guaranteed" means here

  • Non-deterministic & compiler-specific. The window's contents depend on what you do with the mouse and keyboard, and the FFI uses MLton's _import/_address C interface. It is therefore MLton-only and not part of the byte-identical dual-compiler test suite.
  • Targets MLton on macOS (darwin). The shim is built and verified against MLton 20210117 on macOS/arm64, linking minifb's Cocoa/Metal backend. minifb itself is cross-platform (Windows, X11, Wayland), so porting the link flags is the only work needed elsewhere — but this repo only claims macOS.
  • The pure logic is still dual-compiler tested. The two FFI-free halves — WinInput (raw OS poll → Ui.frameinput) and Settings (the demo's model: view + update) — are ordinary total functions and pass byte-identically on both MLton and Poly/ML (40 deterministic checks). CI runs those on both compilers and additionally type-checks the impure shim under MLton; it never opens a window.

How minifb is linked

minifb is not vendored into the repo; instead make minifb fetches it and builds it into a static archive that MLton links against. This keeps the C backend (which is platform Objective-C on macOS) out of the SML source tree while making the build fully reproducible:

make minifb     # git clone emoon/minifb into third_party/, cmake-build libminifb.a

The C shim c/smlwin.c (a ~150-line wrapper: open / blit RGBA8 / poll mouse+keyboard / close) is compiled and linked by MLton together with the SML:

mlton -default-ann 'allowFFI true' \
  -cc-opt   '-Ithird_party/minifb/include' \
  -link-opt 'third_party/minifb/build/libminifb.a \
             -framework Cocoa -framework Metal -framework MetalKit \
             -framework QuartzCore -lc++' \
  -output bin/demo examples/sources.mlb c/smlwin.c

(-lc++ is needed because minifb's static archive contains a C++ translation unit and MLton links with cc, not c++.)

Build & run

make minifb      # one-time: fetch + build the minifb static library
make demo        # build bin/demo (MLton + the FFI shim)
make run         # build + open the interactive window  (macOS, NEEDS A DISPLAY)

make test        # the PURE test suite under MLton (deterministic, no window)
make test-poly   # the PURE test suite under Poly/ML (byte-identical)
make all-tests   # both — must agree

./bin/demo --shot assets/window.png   # drive the live UI on screen + save the frame

Architecture (the pure / impure split)

   OS events                                          pixels on screen
      │                                                      ▲
      ▼                                                      │
 Window.poll ──► WinInput.step ──► Ui.render ──► Settings.update ──► Window.update
  (impure FFI)     (PURE)           (PURE, sml-ui)    (PURE)          (impure FFI/blit)
  • WinInput (pure, tested). Turns a raw, OS-agnostic poll snapshot (mouse x/y + button, typed unicode code points, special keys) into the pure Ui.frameinput: button press/release edges become Mouse(Down)/Mouse(Up) (the toolkit's "click"), pointer motion becomes Mouse(Move), code points become UTF-8 Chars, and Tab becomes FocusNext.
  • Settings (pure, tested). The demo's whole application model: view builds the sml-ui widget tree from the model, and update folds the toolkit's fired events (toggle, select, change, tab, menu, open, close, input, click) back into it.
  • Window (impure, MLton _import). The thin minifb shim: open_, update (blit an Image.image + pump events), poll (→ WinInput.raw), waitSync, close.

Because the entire input→model→view path is pure, the interesting behaviour is unit-tested headlessly (including an integration test that routes a WinInput-produced click through the live sml-ui engine). The window driver itself is smoke-tested by actually opening the window on macOS — the screenshots above are that run.

Layout

Layout B. Vendors sml-ui and its entire transitive pure dependency diamond (sml-color, sml-inflate, sml-image, sml-raster, sml-pretty, sml-svg, sml-canvas2d, sml-font, sml-unicode, sml-text-layout, sml-layout, sml-signal) verbatim under lib/, loaded as one flat, single-copy .mlb (src/deps.mlb) so the shared Image.image type elaborates exactly once. The impure edge is just c/smlwin.c + src/window.sml.

License

MIT — see LICENSE.

About

Impure minifb desktop-window backend for the pure sml-ui toolkit: opens a real OS window and runs the live interactive widget demo (MLton FFI, macOS). Quarantined impure tool.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors