Skip to main content

Architecture

One engine, many frontends

DasherCore owns everything that must be identical on every platform: the language models, the node tree, the rendering maths, the settings/parameter system, alphabets, and the input filters. It exposes a small, flat C API through a single header, dasher.h, documented in docs/C_API.md.

Each frontend owns only:

  1. Input — capturing pointer coordinates, switch events, joystick axes, eye-gaze samples, and feeding them to the engine.
  2. Rendering — drawing the engine’s draw-command buffer onto a canvas (text measuring is the frontend’s job).
  3. UI chrome — toolbars, settings UI, onboarding, platform integration (clipboard, TTS, keyboard extensions).

How frontends consume DasherCore

All three v6 frontends currently include DasherCore as a git submodule and build the C API from source as part of their own build process. This is useful while the C API is still evolving — you get the latest changes, can step into the engine from a debugger, and can test against unreleased DasherCore commits.

FrontendBuild integration
AppleXcodeGen compiles DasherCore sources into a per-platform static library; Swift calls the C API via a bridging header (#import "dasher.h").
WindowsCMake builds DasherCore into dasher.dll; C# calls through P/Invoke.
GTKCMake builds DasherCore into libdasher.so and links it into the GTK executable.

Alternative: consume a pinned binary

You don’t have to build from source. DasherCore’s GitHub Releases ship ready-to-use artefacts for each platform:

  • The shared library (dasher.dll / libdasher.so / libdasher.dylib)
  • The Data/ directory (alphabets, colour schemes, training text)
  • The dasher.h header

This is a sensible approach for new integrations — main will fluctuate, so pinning to a tagged release protects you from breaking changes. The frontends will likely move to this model once the C API stabilises.

Contracts every frontend must honour

From C_API.md’s “Important notes” — the implicit contract:

  • Call dasher_set_screen_size() before dasher_frame().
  • Returned string pointers are ephemeral — copy them immediately; they’re valid only until the next API call.
  • A dasher_ctx is not thread-safe. One thread per context.
  • The engine does no font rendering — the frontend measures text width.
  • out_command_count is an int count, not a command count.
  • Speed is a percentage mapped non-linearly to bitrate.
  • alpha == 0 draw commands are skipped by the frontend.

Single sources of truth

Diagnostic vs. stable API

Functions under the “Test / diagnostic hooks” section of dasher.h are not stable and not for production frontends — they exist to validate a future rewrite. Stick to the public API above that section.