diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 22b37ea6c..2c4553c12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,11 +161,6 @@ jobs: - name: Build the example repos against this tree if: matrix.name == 'Linux' run: bash scripts/ci-retry.sh bash scripts/check-examples.sh - # A plain dvui app with tape playback, on the SDK package alone. In this repo until the - # SDK release that carries `replay` (fizzyedit/fizzy#281). - - name: Build examples/replay-app - if: matrix.name == 'Linux' - run: (cd examples/replay-app && bash "$GITHUB_WORKSPACE/scripts/ci-retry.sh" zig build --summary all) - name: Verify SDK version / ABI fingerprint lock shell: bash diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 752355d04..000000000 --- a/examples/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Examples - -Fizzy's examples live in repos of their own, which CI builds against every pull request -(`scripts/check-examples.sh`): - -- [fizzyedit/example-app](https://github.com/fizzyedit/example-app): fizzy as a library, in - every layout shape (`zig build run-fizzy -Dshape=minimal|studio|endless`). -- [fizzyedit/example-plugin](https://github.com/fizzyedit/example-plugin): the smallest plugin, - the template to copy. - -## replay-app - -Not fizzy at all: a plain dvui app (dvui's own SDL3 backend) with tape playback from -`sdk/replay/`. It plays a live tape into its window at launch, draws the tape's pointer, and -prints a snapshot of its screen. - -It depends only on the SDK package (`sdk/`), and builds `tape` and `replay` against its own dvui -with `@import("fizzy_sdk").replay.modules(…)`: the whole of what any dvui app needs for tape -playback. It moves to example-app once an SDK release carries `replay` -(fizzyedit/fizzy#281). diff --git a/examples/replay-app/build.zig b/examples/replay-app/build.zig deleted file mode 100644 index aa7ab870f..000000000 --- a/examples/replay-app/build.zig +++ /dev/null @@ -1,36 +0,0 @@ -//! A plain dvui app — no fizzy — that plays a tape into its own window (`replay`), draws the -//! tape's pointer, and prints what is on screen as text. The whole of what it takes to give any -//! dvui app tape playback. -const std = @import("std"); -const fizzy_sdk = @import("fizzy_sdk"); - -pub fn build(b: *std.Build) !void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - - // dvui as any app has it: the SDK pins it, and this app picks its own backend. - const sdk = b.dependency("fizzy_sdk", .{ .target = target, .optimize = optimize }); - const dvui_dep = sdk.builder.dependency("dvui", .{ .target = target, .optimize = optimize, .backend = .sdl3 }); - const dvui_mod = dvui_dep.module("dvui_sdl3"); - - // `tape` and `replay`, built against that dvui. - const automation = fizzy_sdk.replay.modules(b, sdk.builder, dvui_mod, target, optimize); - - const exe = b.addExecutable(.{ - .name = "replay-app", - .root_module = b.createModule(.{ - .target = target, - .optimize = optimize, - .root_source_file = b.path("src/main.zig"), - }), - }); - exe.root_module.addImport("dvui", dvui_mod); - exe.root_module.addImport("tape", automation.tape); - exe.root_module.addImport("replay", automation.replay); - b.installArtifact(exe); - - const run = b.addRunArtifact(exe); - run.step.dependOn(b.getInstallStep()); - if (b.args) |args| run.addArgs(args); - b.step("run", "Run the replay example").dependOn(&run.step); -} diff --git a/examples/replay-app/build.zig.zon b/examples/replay-app/build.zig.zon deleted file mode 100644 index 1b850b094..000000000 --- a/examples/replay-app/build.zig.zon +++ /dev/null @@ -1,11 +0,0 @@ -.{ - .name = .replay_app, - .version = "0.1.0", - .fingerprint = 0x75afa6515ed5834c, - .minimum_zig_version = "0.16.0", - .dependencies = .{ - // Only the SDK package: its pinned dvui and `tape` / `replay`. Nothing of fizzy the app. - .fizzy_sdk = .{ .path = "../../sdk" }, - }, - .paths = .{ "build.zig", "build.zig.zon", "src" }, -} diff --git a/examples/replay-app/src/main.zig b/examples/replay-app/src/main.zig deleted file mode 100644 index 615115d80..000000000 --- a/examples/replay-app/src/main.zig +++ /dev/null @@ -1,123 +0,0 @@ -//! A plain dvui app with tape playback, and nothing of fizzy's. -//! -//! At launch it plays a live tape into its own window: two clicks on Count, a click into the field -//! and some typing, a command that resets the count, and one more click — so it ends on 1. The tape aims at widgets by their tags, so it plays at any -//! window size; the tape's pointer and its clicks are drawn over the app (`replay.overlay`); a -//! click or key from a person stops it. When it ends, the app prints what is on screen, as text -//! (`replay.Snapshot`) — the names a test or an automation client reads instead of pixels. -//! -//! What an app gives `replay`: a `Stage` (`idle` and `command` are enough for a live tape), -//! `LiveDriver.frame` and `Snapshot.beginFrame` first thing in its frame, and the overlay and -//! `Snapshot.endFrame` last. -const std = @import("std"); -const dvui = @import("dvui"); -const replay = @import("replay"); -const Script = @import("tape").Script; - -pub const dvui_app: dvui.App = .{ - .config = .{ .options = .{ - .size = .{ .w = 520, .h = 360 }, - .title = "Replay example", - } }, - .frameFn = frame, - .initFn = init, - .deinitFn = deinit, -}; -pub const main = dvui.App.main; -pub const panic = dvui.App.panic; -pub const std_options: std.Options = .{ .logFn = dvui.App.logFn }; - -var gpa: std.mem.Allocator = undefined; -var count: usize = 0; -var driver: replay.LiveDriver = undefined; -var snapshot: replay.Snapshot = undefined; -/// The snapshot asked for when the last tape ended, until it is printed. -var shot: ?u32 = null; -var played_once = false; -/// The last tape's end has been read back. -var reported = true; - -// ---- the stage: what this app is to a tape ------------------------------------------------- - -const stage_vtable: replay.Stage.VTable = .{ .idle = idle, .command = command }; - -/// Nothing here loads in the background: always settled. -fn idle(_: *anyopaque) bool { - return true; -} - -/// The one command this app offers a tape. -fn command(_: *anyopaque, id: []const u8, _: []const u8) void { - if (std.mem.eql(u8, id, "example.reset")) count = 0; -} - -// ---- the app ------------------------------------------------------------------------------- - -fn init(win: *dvui.Window) !void { - gpa = win.gpa; - driver = .init(.{ .ctx = &count, .vtable = &stage_vtable }); - snapshot = .init(gpa); -} - -fn deinit(_: *dvui.Window) void { - driver.deinit(); - snapshot.deinit(); -} - -/// The tape: written with `tape.Script`, aimed at tags rather than positions. -fn demoTape() !@import("tape").Tape.Owned { - var s: Script = .init(gpa, "example", "Count, type, reset"); - errdefer s.deinit(); - s.check = replay.Input.check; - s.check.live = true; - try s.click(.{ .tag = "example.count" }, .{}); - try s.click(.{ .tag = "example.count" }, .{}); - try s.click(.{ .tag = "example.field", .x = 0.5, .y = 0.5 }, .{}); - try s.typeText("typed by a tape", .{}); - s.pause(600); - try s.command("example.reset"); - try s.click(.{ .tag = "example.count" }, .{}); - return s.finish(); -} - -fn play() void { - driver.play(demoTape() catch return) catch |err| return std.log.err("tape refused: {t}", .{err}); - reported = false; -} - -fn frame() !dvui.App.Result { - // First, before anything reads the frame's events. - snapshot.beginFrame(); - driver.frame(); - if (!played_once) { - played_once = true; - play(); - } - - { - var box = dvui.box(@src(), .{ .dir = .vertical }, .{ .expand = .both, .padding = .all(16), .background = true, .style = .window }); - defer box.deinit(); - dvui.label(@src(), "Clicked {d} times", .{count}, .{}); - if (dvui.button(@src(), "Count", .{}, .{ .tag = "example.count" })) count += 1; - var entry = dvui.textEntry(@src(), .{}, .{ .tag = "example.field", .expand = .horizontal }); - entry.deinit(); - if (dvui.button(@src(), "Play the tape again", .{}, .{}) and !driver.playing()) play(); - if (driver.outcome) |o| dvui.label(@src(), "Last tape: {t}", .{o}, .{}); - } - - // When a tape ends, read the screen back as text. - if (!driver.playing() and !reported) { - reported = true; - std.debug.print("The tape ended ({any}); the count is {d}.\n", .{ driver.outcome, count }); - shot = snapshot.request(); - } - if (shot) |n| if (snapshot.get(n)) |text| { - std.debug.print("What is on screen:\n{s}", .{text}); - shot = null; - }; - - // Last, over everything: the tape's pointer, then the snapshot written out. - replay.overlay.drawLive(&driver, .{}); - snapshot.endFrame(); - return .ok; -} diff --git a/scripts/check-examples.sh b/scripts/check-examples.sh index ac7251bc3..476f2c03b 100755 --- a/scripts/check-examples.sh +++ b/scripts/check-examples.sh @@ -7,8 +7,8 @@ # dependency does. A path dependency (or `zig build --fork`) would see the whole checkout and # miss a file left out of `.paths`. # -# example-app gets the whole repo; example-plugin gets the plugin SDK, packed as a release would -# be (`scripts/pack-sdk.sh`). +# example-app gets the whole repo, and for its replay app the plugin SDK; example-plugin gets the +# plugin SDK. The SDK is packed as a release would be (`scripts/pack-sdk.sh`). # # Usage: # scripts/check-examples.sh # clones both repos' main @@ -57,10 +57,14 @@ echo "== example-app, against this tree" ( cd "$work/example-app" zig fetch --save=fizzy "$work/fizzy.tar.gz" >/dev/null + # Its replay app depends on the plugin SDK alone: this tree's, packed as a release would be. + zig fetch --save=fizzy_sdk "$sdk_tarball" >/dev/null for shape in minimal studio endless; do echo "-- $shape" zig build -Dshape="$shape" --summary all done echo "-- studio, as data" zig build -Dshape=studio -Dzon-layout=true --summary all + echo "-- the replay app" + zig build replay --summary all ) diff --git a/sdk/replay_module.zig b/sdk/replay_module.zig index 07572cf9c..508921ff4 100644 --- a/sdk/replay_module.zig +++ b/sdk/replay_module.zig @@ -12,7 +12,7 @@ //! exe.root_module.addImport("replay", automation.replay); //! ``` //! -//! `examples/replay-app` is the whole of it in a plain dvui app. +//! fizzyedit/example-app's replay app (`replay/main.zig`) is the whole of it in a plain dvui app. //! //! Pure `std.Build` glue — lives in the `sdk/` package so it ships in the tarball. const std = @import("std");