@vibecook/ice 0.15.0-desk.2 → 0.15.0-desk.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/{chunk-52GMQ2BN.js → chunk-DNMUIKNE.js} +154 -4
- package/dist/chunk-DNMUIKNE.js.map +1 -0
- package/dist/desk-objects.js +1 -1
- package/dist/desk.js +5 -1
- package/dist/types/packages/desk/src/index.d.ts +1 -0
- package/dist/types/packages/desk/src/still.d.ts +111 -0
- package/package.json +1 -1
- package/dist/chunk-52GMQ2BN.js.map +0 -1
package/README.md
CHANGED
|
@@ -102,7 +102,9 @@ export const Clock = defineObject({
|
|
|
102
102
|
- **Being a container** — `ObjectKind.face` and `faceLaw: { radius, chips, finishes }`; a child's `chip()` names its finish.
|
|
103
103
|
- **Held tools and menu acts** — a tool's `glyph` is a name of the bar's set or its own `{ path }`; `menu` acts show for a
|
|
104
104
|
selection of the kind and run through `ops.runMenuAction`.
|
|
105
|
-
- **Stills** — `handle.pinAsset(entity, asset)` pins the kind's own `ctx.asset
|
|
105
|
+
- **Stills** — `handle.pinAsset(entity, asset)` pins the kind's own `ctx.asset`; and a kind's pixel proof needs no desk layer:
|
|
106
|
+
`createStill({ device, format, size, dpr, objects, stage })` draws ONE frame on your device (Dawn in Node, or a browser's), no
|
|
107
|
+
canvas — `stage` lays its world (`engine.ops.spawnWidget`, `pinAsset`) — and hands back its RGBA to hold to a golden of your own.
|
|
106
108
|
|
|
107
109
|
React and `react-dom` are **optional** peer dependencies — the core, desk and dom
|
|
108
110
|
entries are React-free; `three` is imported nowhere.
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
HOLD,
|
|
19
19
|
LAYER_IDLE_MS,
|
|
20
20
|
MARKS,
|
|
21
|
+
MAT,
|
|
21
22
|
MAT_GRID,
|
|
22
23
|
MISSING,
|
|
23
24
|
MatUniforms,
|
|
@@ -75,6 +76,7 @@ import {
|
|
|
75
76
|
smoothstep,
|
|
76
77
|
solveFlightStart,
|
|
77
78
|
spring,
|
|
79
|
+
themeFrom,
|
|
78
80
|
tilted
|
|
79
81
|
} from "./chunk-K4HUZAYJ.js";
|
|
80
82
|
import {
|
|
@@ -132,6 +134,7 @@ import {
|
|
|
132
134
|
WidgetEquipped,
|
|
133
135
|
closeTray,
|
|
134
136
|
compareStackOrder,
|
|
137
|
+
createCanvasEngine,
|
|
135
138
|
createSiblingOrderIndex,
|
|
136
139
|
currentNavFrame,
|
|
137
140
|
defineQuery,
|
|
@@ -3356,8 +3359,8 @@ function renderHeldFrame(device, hold, root, pool, grid, into, inputs, held, cac
|
|
|
3356
3359
|
device.queue.submit([encoder.finish()]);
|
|
3357
3360
|
return cache.stats ?? { k0: 0, fade: 0, wind: false, kinds: hand.kinds, outgoing: null, portals: 0 };
|
|
3358
3361
|
}
|
|
3359
|
-
var captureNumber = (what, v,
|
|
3360
|
-
if (typeof v !== "number" || !Number.isFinite(v) ||
|
|
3362
|
+
var captureNumber = (what, v, positive2) => {
|
|
3363
|
+
if (typeof v !== "number" || !Number.isFinite(v) || positive2 && v <= 0) throw new Error(`capture: ${what} must be a ${positive2 ? "positive " : ""}finite number (got ${String(v)})`);
|
|
3361
3364
|
return v;
|
|
3362
3365
|
};
|
|
3363
3366
|
function checkCapture(opts) {
|
|
@@ -8166,6 +8169,151 @@ async function ablateKinds(a, opts = {}) {
|
|
|
8166
8169
|
return { frames, rounds, base: baseS, control: sampled(c), aa: median(c) - baseS.median, noise, kinds: out, samples: Object.fromEntries(ms) };
|
|
8167
8170
|
}
|
|
8168
8171
|
|
|
8172
|
+
// ../desk/src/still.ts
|
|
8173
|
+
async function createStillDesk(opts) {
|
|
8174
|
+
const mat = await CuttingMat.create(opts.device, opts.format, matShaders(shaderText(MAT_SHADER_FILES)));
|
|
8175
|
+
let root;
|
|
8176
|
+
try {
|
|
8177
|
+
root = await createSlotSet(opts.device, opts.format, mat, opts.kinds, opts.onError);
|
|
8178
|
+
} catch (err) {
|
|
8179
|
+
mat.dispose();
|
|
8180
|
+
throw err;
|
|
8181
|
+
}
|
|
8182
|
+
mat.setNoise(blueNoise());
|
|
8183
|
+
const pool = new SlotPool(root);
|
|
8184
|
+
let disposed = false;
|
|
8185
|
+
return {
|
|
8186
|
+
mat,
|
|
8187
|
+
root,
|
|
8188
|
+
pool,
|
|
8189
|
+
dispose() {
|
|
8190
|
+
if (disposed) return;
|
|
8191
|
+
disposed = true;
|
|
8192
|
+
pool.dispose();
|
|
8193
|
+
root.card?.dispose();
|
|
8194
|
+
for (const k of [...root.kinds.values()].reverse()) k.pass.dispose();
|
|
8195
|
+
root.missing?.dispose();
|
|
8196
|
+
mat.dispose();
|
|
8197
|
+
}
|
|
8198
|
+
};
|
|
8199
|
+
}
|
|
8200
|
+
var FORMATS = ["rgba8unorm", "bgra8unorm"];
|
|
8201
|
+
var THEMES = ["light", "dark"];
|
|
8202
|
+
var STILL_PALETTE = { canvasBg: MAT.ground, select: MARKS.inks.pencil };
|
|
8203
|
+
var positive = (what, v) => {
|
|
8204
|
+
if (typeof v !== "number" || !Number.isFinite(v) || v <= 0) throw new Error(`createStill: ${what} must be a positive finite number (got ${String(v)})`);
|
|
8205
|
+
return v;
|
|
8206
|
+
};
|
|
8207
|
+
var finite = (what, v) => {
|
|
8208
|
+
if (typeof v !== "number" || !Number.isFinite(v)) throw new Error(`createStill: ${what} must be a finite number (got ${String(v)})`);
|
|
8209
|
+
return v;
|
|
8210
|
+
};
|
|
8211
|
+
function kindsOf2(objects) {
|
|
8212
|
+
const byName = /* @__PURE__ */ new Map();
|
|
8213
|
+
for (const t of objects) {
|
|
8214
|
+
const k = objectKindOf(t);
|
|
8215
|
+
if (k === void 0) throw new Error(`createStill: "${t.type}" is not a desk object \u2014 a still draws object types (\`defineObject\`)`);
|
|
8216
|
+
if (!byName.has(k.name)) byName.set(k.name, k);
|
|
8217
|
+
}
|
|
8218
|
+
return [...byName.values()];
|
|
8219
|
+
}
|
|
8220
|
+
var SCOPES2 = ["validation", "out-of-memory", "internal"];
|
|
8221
|
+
var watched2 = (device) => typeof device.pushErrorScope === "function";
|
|
8222
|
+
var pushScopes2 = (device) => {
|
|
8223
|
+
if (watched2(device)) for (const f of SCOPES2) device.pushErrorScope(f);
|
|
8224
|
+
};
|
|
8225
|
+
var popScopes2 = (device) => watched2(device) ? Promise.all(SCOPES2.map(() => device.popErrorScope())).then((errors) => errors.find((e) => e !== null) ?? null) : Promise.resolve(null);
|
|
8226
|
+
var gpuError = (e) => `${e.constructor?.name ?? "GPUError"}: ${e.message}`;
|
|
8227
|
+
var queues = /* @__PURE__ */ new WeakMap();
|
|
8228
|
+
function inTurn(device, run) {
|
|
8229
|
+
const turn = (queues.get(device) ?? Promise.resolve()).then(run);
|
|
8230
|
+
queues.set(device, turn.then(() => void 0, () => void 0));
|
|
8231
|
+
return turn;
|
|
8232
|
+
}
|
|
8233
|
+
function createStill(opts) {
|
|
8234
|
+
if (typeof opts !== "object" || opts === null) throw new Error("createStill: options are required");
|
|
8235
|
+
if (typeof opts.device !== "object" || opts.device === null) throw new Error("createStill: `device` is required \u2014 the caller's GPUDevice");
|
|
8236
|
+
if (!FORMATS.includes(opts.format)) throw new Error(`createStill: format must be ${FORMATS.map((f) => `"${f}"`).join(" or ")} (got ${String(opts.format)})`);
|
|
8237
|
+
const width = positive("size.width", opts.size?.width);
|
|
8238
|
+
const height = positive("size.height", opts.size?.height);
|
|
8239
|
+
const dpr = positive("dpr", opts.dpr);
|
|
8240
|
+
if (!Array.isArray(opts.objects)) throw new Error("createStill: `objects` must be a list of object types (`defineObject`)");
|
|
8241
|
+
const kinds = kindsOf2(opts.objects);
|
|
8242
|
+
const theme = opts.theme ?? "light";
|
|
8243
|
+
if (!THEMES.includes(theme)) throw new Error(`createStill: theme must be "light" or "dark" (got ${String(theme)})`);
|
|
8244
|
+
const cam = opts.camera === void 0 ? { x: -width / 2, y: -height / 2, zoom: 1 } : { x: finite("camera.x", opts.camera.x), y: finite("camera.y", opts.camera.y), zoom: positive("camera.zoom", opts.camera.zoom) };
|
|
8245
|
+
if (typeof opts.stage !== "function") throw new Error("createStill: `stage` must be a function \u2014 it lays the still's world");
|
|
8246
|
+
const plan = { width, height, dpr, kinds, theme, palette: opts.palette ?? STILL_PALETTE, cam };
|
|
8247
|
+
return inTurn(opts.device, () => drawStill(opts, plan));
|
|
8248
|
+
}
|
|
8249
|
+
async function drawStill(opts, plan) {
|
|
8250
|
+
const { device, format } = opts;
|
|
8251
|
+
const { width, height, dpr, cam } = plan;
|
|
8252
|
+
let unattributed2 = null;
|
|
8253
|
+
const desk = await createStillDesk({ device, format, kinds: plan.kinds, onError: (e) => {
|
|
8254
|
+
unattributed2 ??= e;
|
|
8255
|
+
} });
|
|
8256
|
+
let engine;
|
|
8257
|
+
let builder;
|
|
8258
|
+
try {
|
|
8259
|
+
const refused = desk.root.faults?.[0];
|
|
8260
|
+
if (refused !== void 0) throw new Error(`createStill: the kind "${refused.kind}" was ${refused.reason}`);
|
|
8261
|
+
if (unattributed2 !== null) throw new Error(`createStill: a GPU error while the kinds were made, no kind's alone \u2014 ${gpuError(unattributed2)}`);
|
|
8262
|
+
const theme = themeFrom(plan.theme, plan.palette);
|
|
8263
|
+
const looks = looksOf(plan.kinds, plan.palette, theme);
|
|
8264
|
+
engine = createCanvasEngine({ widgets: [...opts.objects] });
|
|
8265
|
+
engine.docs.create();
|
|
8266
|
+
const world = engine.world;
|
|
8267
|
+
world.setResource(Viewport, { w: width, h: height, dpr });
|
|
8268
|
+
world.setResource(Camera, { x: cam.x, y: cam.y, zoom: cam.zoom, gesturing: false });
|
|
8269
|
+
const b = createDeskBuilder(world, { objects: [...opts.objects] });
|
|
8270
|
+
builder = b;
|
|
8271
|
+
await opts.stage({ engine, world, pinAsset: (e, asset) => b.pin(e, asset), pinFlux: (e, targets) => b.pinFlux(e, targets) });
|
|
8272
|
+
engine.step(16);
|
|
8273
|
+
engine.step(32);
|
|
8274
|
+
b.changed();
|
|
8275
|
+
const built = b.build(cam, { width, height, dpr }, 0, theme, DEFAULT_GRID, looks, { now: 0 });
|
|
8276
|
+
const inputs = {
|
|
8277
|
+
view: { camX: cam.x, camY: cam.y, zoom: cam.zoom, width, height, dpr },
|
|
8278
|
+
grid: built.grid,
|
|
8279
|
+
objects: built.objects,
|
|
8280
|
+
...built.portals.length > 0 ? { portals: built.portals } : {},
|
|
8281
|
+
...built.lodZoom !== void 0 ? { lodZoom: built.lodZoom } : {},
|
|
8282
|
+
...built.present !== void 0 ? { present: built.present } : {},
|
|
8283
|
+
...built.light !== void 0 ? { light: built.light } : {},
|
|
8284
|
+
...built.outgoing !== void 0 ? { outgoing: built.outgoing } : {},
|
|
8285
|
+
theme
|
|
8286
|
+
};
|
|
8287
|
+
const passes = { root: desk.root, pool: desk.pool, grid: built.grid, marks: null, hold: null, tray: null, traySlots: null };
|
|
8288
|
+
pushScopes2(device);
|
|
8289
|
+
let shot;
|
|
8290
|
+
let threw = null;
|
|
8291
|
+
try {
|
|
8292
|
+
shot = await captureFrame(device, passes, format, inputs, { stamp: null, stats: null, copies: 0 });
|
|
8293
|
+
} catch (err) {
|
|
8294
|
+
threw = { err };
|
|
8295
|
+
}
|
|
8296
|
+
const raised = await popScopes2(device);
|
|
8297
|
+
if (threw !== null) throw threw.err;
|
|
8298
|
+
if (raised !== null) throw new Error(`createStill: a GPU error while the still was drawn \u2014 ${gpuError(raised)}`);
|
|
8299
|
+
if (shot === void 0) throw new Error("createStill: the device was lost before the still was read back");
|
|
8300
|
+
const rgba = shot.bytes;
|
|
8301
|
+
if (format === "bgra8unorm") {
|
|
8302
|
+
for (let i = 0; i < rgba.length; i += 4) {
|
|
8303
|
+
const blue = rgba[i];
|
|
8304
|
+
rgba[i] = rgba[i + 2];
|
|
8305
|
+
rgba[i + 2] = blue;
|
|
8306
|
+
}
|
|
8307
|
+
}
|
|
8308
|
+
return { width: shot.width, height: shot.height, rgba, dispose() {
|
|
8309
|
+
} };
|
|
8310
|
+
} finally {
|
|
8311
|
+
builder?.dispose();
|
|
8312
|
+
engine?.dispose();
|
|
8313
|
+
desk.dispose();
|
|
8314
|
+
}
|
|
8315
|
+
}
|
|
8316
|
+
|
|
8169
8317
|
export {
|
|
8170
8318
|
KIND_STRIKES,
|
|
8171
8319
|
KIND_MISSING,
|
|
@@ -8264,6 +8412,8 @@ export {
|
|
|
8264
8412
|
inkRaster,
|
|
8265
8413
|
kindsIn,
|
|
8266
8414
|
withoutKind,
|
|
8267
|
-
ablateKinds
|
|
8415
|
+
ablateKinds,
|
|
8416
|
+
STILL_PALETTE,
|
|
8417
|
+
createStill
|
|
8268
8418
|
};
|
|
8269
|
-
//# sourceMappingURL=chunk-
|
|
8419
|
+
//# sourceMappingURL=chunk-DNMUIKNE.js.map
|