diff options
Diffstat (limited to 'docs/getting-started.md')
| -rw-r--r-- | docs/getting-started.md | 81 |
1 files changed, 35 insertions, 46 deletions
diff --git a/docs/getting-started.md b/docs/getting-started.md index d21c9bd..caa25eb 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -39,79 +39,68 @@ CPU pixel targets are presented through the system's Metal device; applications do not need to create or manage that device themselves. The complete beginner example is [hello.c](../examples/hello.c). It checks -construction failures, fills every pixel, presents inside `draw`, drains input, -responds to quit/close/lost, and destroys resources in order. The +construction failures, fills every pixel, and presents inside a frame callback. +`yasl_run()` handles input delivery, display notifications, and cleanup. The [interactive window](../examples/simple_window.c) adds pointer input; the [tablet example](../examples/tablet.c) demonstrates retained application content, pressure, erasers, resizing, and scale changes. ## Link an application -Install the library and public headers into your chosen prefix: +Install the shared and static libraries into your chosen prefix. Headers, +examples, documentation, and pkg-config metadata remain in the source tree: ```sh -meson setup build --prefix=/usr/local +meson setup build --prefix=/usr/local --libdir=lib meson compile -C build meson install -C build -cc -std=c23 examples/hello.c -o hello $(pkg-config --cflags --libs yasl) +cc -std=c23 -Iinclude examples/hello.c -o hello -L/usr/local/lib -Wl,-rpath,/usr/local/lib -lyasl ./hello ``` -The prefix must be writable, and your compiler, pkg-config, and runtime loader -must search it. For a custom prefix, set `PKG_CONFIG_PATH` to its pkg-config -directory and configure the loader for its library directory. Static linking -uses `pkg-config --static --libs yasl` to include backend dependencies. +The prefix must be writable. Use matching headers from `include/`, and adjust +the library search path and runtime path for your chosen prefix and `libdir`. +Static consumers must also link the enabled backends' dependencies. -A Meson consumer uses the installed dependency: +A Meson application can instead vendor the source under `subprojects/yasl`: ```meson project('my-app', 'c', default_options: ['c_std=c23']) -yasl = dependency('yasl', version: '>=0.1.0') +yasl = subproject('yasl').get_variable('yasl_dep') executable('my-app', 'main.c', dependencies: yasl) ``` -YASL also declares `meson.override_dependency('yasl', ...)`, so the same consumer -can use a vendored Meson subproject through a fallback dependency. Public headers -can be included from C++11 or newer; the library itself builds as C23. +The subproject dependency includes headers and backend link dependencies. +Public headers can be included from C++11 or newer; the library itself builds +as C23. Only the library artifacts are installed by `meson install`. ## The application cycle -1. Open a display with `yasl_display_open(NULL, &spec)`. NULL creates a loop owned - by the display. Supply your own loop only when you need shared loop ownership. -2. Create a toplevel with `yasl_window_spec`: supply a positive **logical-pixel** - size, a `yasl_window_cbs` table in `cbs`, and callback userdata in `ud`. - Zero-initialize every option and callback struct. Callback tables are copied; - userdata must remain alive. The new window's callbacks start after creation - returns. Read initial geometry with `yasl_surface_geometry()`. -3. Schedule the initial redraw. `draw` receives a borrowed target. Fill every - pixel with premultiplied `0xAARRGGBB`, then present that exact target, once. -4. Dispatch, drain input for every live surface queue, update application state, - and flush. Flush runs scheduled drawing and sends native requests. Dispatch - may also invoke callbacks, including drawing during native live resize. -5. Destroy popups before parents, surfaces before displays, and displays before - any supplied loop. NULL destroy/close calls do nothing; freed pointers are - invalid for every operation. +1. Include `<yasl/app.h>` and initialize a `yasl_app_desc` with your userdata and + `init`, `event`, and `frame` callbacks. Call `yasl_run(&desc)`. +2. In `init`, create a toplevel with a positive **logical-pixel** size and call + `yasl_surface_request_frame(surface)` for the first redraw. +3. In `event`, handle the union member selected by `event->type`. Return + `YASL_APP_QUIT` for a close request; otherwise return `YASL_APP_CONTINUE`. +4. In `frame`, fill every pixel in `frame->cpu.pixels` with premultiplied + `0xAARRGGBB` and present once with `yasl_frame_present_cpu(frame, NULL, 0)`. +5. Let the runner close remaining surfaces and the display. Release your own + resources in the optional `quit` callback or after `yasl_run()` returns. ```c -while (running) { - if (yasl_display_dispatch(display, -1) < 0) { - perror("yasl_display_dispatch"); - break; - } - struct yasl_input_event event; - while (yasl_surface_input_poll(surface, &event)) { - /* Read the union member selected by event.kind. */ - } - yasl_display_flush(display); -} +struct yasl_app_desc desc = { + .app_id = "org.example.app", + .userdata = &app, + .init = init, + .event = event, + .frame = draw, +}; +return yasl_run(&desc); ``` -Zero timeout polls, positive timeout bounds the wait in milliseconds, and a -negative timeout waits for work. Undrained input makes dispatch return without -waiting. Use the return value only to detect failure, not to count input events. -If callbacks destroy surfaces, update your application registry immediately and -only poll surfaces that are still alive. Arrange display/loop cleanup after the -cycle ends; destroying them inside a callback is unsupported. +The default pacing mode sleeps until input, resize, or a requested redraw. +Use `YASL_PACING_CONTINUOUS` for an animation or game. The core API still supports +manual dispatch/poll/flush when an application owns its event loop; see the guide. See the [application guide](guide.md) for drawing, input, popups, timers, and platform limits, or the comments in the [public header](../include/yasl/yasl.h) |
