@typecad/cuttlefish 1.0.0-alpha.7 → 1.0.0-alpha.8
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/dist/api/config.d.ts +32 -0
- package/dist/api/index.d.ts +1 -1
- package/dist/api/schema/types.d.ts +15 -0
- package/dist/api/shared/async-runtime-static.d.ts +12 -1
- package/dist/api/shared/async-runtime-static.js +69 -24
- package/dist/api/shared/async-symbol-detector.d.ts +11 -0
- package/dist/api/shared/async-symbol-detector.js +140 -0
- package/dist/api/shared/async-types.d.ts +24 -0
- package/dist/api/shared/coop-scheduler.d.ts +60 -0
- package/dist/api/shared/coop-scheduler.js +149 -0
- package/dist/api/shared/display-adapter.d.ts +2 -2
- package/dist/api/shared/display-adapter.js +9 -119
- package/dist/api/shared/display-adapters/sdl.js +29 -29
- package/dist/api/shared/display-profile.d.ts +38 -33
- package/dist/api/shared/display-profile.js +22 -170
- package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
- package/dist/api/shared/framework-manifest-registry.js +8 -6
- package/dist/api/shared/framework-manifest.d.ts +147 -28
- package/dist/api/shared/framework-manifest.js +35 -2
- package/dist/api/shared/graphics-strategy.d.ts +15 -6
- package/dist/api/shared/hal-op-ir.d.ts +340 -3
- package/dist/api/shared/hal-op-ir.js +34 -0
- package/dist/api/shared/index.d.ts +9 -1
- package/dist/api/shared/index.js +11 -1
- package/dist/api/shared/ir-core.d.ts +4 -0
- package/dist/api/shared/ir-declarations.d.ts +6 -0
- package/dist/api/shared/platform-strategy.d.ts +104 -2
- package/dist/api/shared/polyfill-helper-registry.js +18 -1
- package/dist/api/shared/promise-runtime.d.ts +1 -1
- package/dist/api/shared/promise-runtime.js +17 -13
- package/dist/api/shared/toolchain-types.d.ts +17 -0
- package/dist/api/shared/validate-framework-manifest.js +77 -0
- package/dist/api/shared/worker-runtime-polyfill.d.ts +22 -0
- package/dist/api/shared/worker-runtime-polyfill.js +34 -0
- package/dist/api/shared/worker-runtime.d.ts +69 -0
- package/dist/api/shared/worker-runtime.js +163 -0
- package/dist/cli.js +120 -121
- package/dist/config-loader.d.ts +7 -2
- package/dist/config-loader.js +20 -19
- package/dist/config-schema.d.ts +107 -65
- package/dist/config-schema.js +14 -0
- package/dist/contract/board-generator.d.ts +17 -0
- package/dist/contract/board-generator.js +57 -0
- package/dist/contract/contract-parser.d.ts +217 -0
- package/dist/contract/contract-parser.js +224 -0
- package/dist/contract/index.d.ts +22 -0
- package/dist/contract/index.js +68 -0
- package/dist/create/board-codegen.js +4 -4
- package/dist/create/board-generators.js +4 -5
- package/dist/create/board-spec.d.ts +74 -77
- package/dist/create/board-spec.js +0 -1
- package/dist/create/init-scaffold.d.ts +7 -3
- package/dist/create/init-scaffold.js +0 -62
- package/dist/create/init-templates.js +62 -16
- package/dist/create/init-wizard.js +32 -27
- package/dist/debug/preprocessor.js +178 -39
- package/dist/debug/types.d.ts +23 -0
- package/dist/diagnostics/mermaid-builder.d.ts +1 -1
- package/dist/diagnostics/mermaid-builder.js +34 -24
- package/dist/emit/compliance/arxml-writer.d.ts +11 -0
- package/dist/emit/compliance/arxml-writer.js +34 -0
- package/dist/emit/compliance/compliance-context.d.ts +57 -0
- package/dist/emit/compliance/compliance-context.js +113 -0
- package/dist/emit/compliance/deviation-ledger.d.ts +27 -0
- package/dist/emit/compliance/deviation-ledger.js +47 -0
- package/dist/emit/compliance/deviation-writer.d.ts +30 -0
- package/dist/emit/compliance/deviation-writer.js +37 -0
- package/dist/emit/compliance/index.d.ts +7 -0
- package/dist/emit/compliance/index.js +6 -0
- package/dist/emit/compliance/rule-engine.d.ts +13 -0
- package/dist/emit/compliance/rule-engine.js +101 -0
- package/dist/emit/compliance/rules.d.ts +16 -0
- package/dist/emit/compliance/rules.js +191 -0
- package/dist/emit/compliance/types.d.ts +59 -0
- package/dist/emit/compliance/types.js +8 -0
- package/dist/emit/emitters/class-emitter.js +6 -1
- package/dist/emit/emitters/emitter-context.d.ts +23 -1
- package/dist/emit/emitters/function-emitter-impl.js +96 -6
- package/dist/emit/emitters/line-appender.js +19 -0
- package/dist/emit/emitters/line-marker.d.ts +38 -0
- package/dist/emit/emitters/line-marker.js +39 -0
- package/dist/emit/emitters/output-finalizer.js +80 -1
- package/dist/emit/emitters/setup.d.ts +17 -0
- package/dist/emit/emitters/setup.js +217 -36
- package/dist/emit/emitters/top-level-prep.js +6 -0
- package/dist/emit/emitters/type-decl-emitter.js +28 -3
- package/dist/emit/emitters/ui-emitter.js +17 -8
- package/dist/emit/expression-renderer.d.ts +1 -1
- package/dist/emit/expression-renderer.js +81 -5
- package/dist/emit/route-hal-op.js +18 -5
- package/dist/emit/snprintf-helpers.js +7 -4
- package/dist/emit/statement-renderer.d.ts +10 -0
- package/dist/emit/statement-renderer.js +21 -5
- package/dist/emit/utils/async-state-machine.js +39 -12
- package/dist/framework-package.js +2 -0
- package/dist/framework-registry.d.ts +17 -0
- package/dist/ir/adc-range-validation.js +14 -1
- package/dist/ir/build-ir-state.d.ts +1 -0
- package/dist/ir/build-ir-state.js +14 -0
- package/dist/ir/build-ir.js +4 -4
- package/dist/ir/call-graph.js +16 -0
- package/dist/ir/expression-to-ir.js +150 -0
- package/dist/ir/function-builder.js +22 -0
- package/dist/ir/hal/hal-emitter.js +10 -6
- package/dist/ir/hal/hal-parser.js +16 -9
- package/dist/ir/hal/hal-plugins.js +164 -3
- package/dist/ir/identifier-collector.js +21 -4
- package/dist/ir/interrupt-analysis.d.ts +5 -1
- package/dist/ir/interrupt-analysis.js +8 -16
- package/dist/ir/ownership-analysis.js +6 -0
- package/dist/ir/pin-capability-validation.js +37 -0
- package/dist/ir/pin-mode-validation.d.ts +2 -2
- package/dist/ir/pin-mode-validation.js +49 -18
- package/dist/ir/program-analysis.d.ts +42 -0
- package/dist/ir/program-analysis.js +243 -6
- package/dist/ir/render-expr.js +11 -0
- package/dist/ir/timing-validation.js +11 -2
- package/dist/ir/transformers/call-statement.js +105 -0
- package/dist/ir/transformers/expressions.js +4 -0
- package/dist/ir/transformers/hal-call-resolver.js +21 -0
- package/dist/ir/transformers/namespace-methods.js +17 -12
- package/dist/ir/transformers/ui-reactive.js +2 -2
- package/dist/ir/transformers/variables.js +51 -0
- package/dist/ir/type-resolution.js +18 -0
- package/dist/ir/ui-element-auto-wire.js +7 -5
- package/dist/ir/utils/map-statements.d.ts +4 -0
- package/dist/ir/utils/map-statements.js +79 -0
- package/dist/ir/validation-orchestrator.js +6 -1
- package/dist/ir/worker-analysis.d.ts +10 -0
- package/dist/ir/worker-analysis.js +261 -0
- package/dist/orchestrator/graph-builder.js +8 -7
- package/dist/platform/coop-scheduler-runtime.d.ts +19 -0
- package/dist/platform/coop-scheduler-runtime.js +41 -0
- package/dist/platform/generic-strategy.d.ts +15 -3
- package/dist/platform/generic-strategy.js +49 -4
- package/dist/safety/safety-bridge.d.ts +11 -0
- package/dist/safety/safety-bridge.js +48 -0
- package/dist/safety/sidecar-bridge.d.ts +5 -0
- package/dist/safety/sidecar-bridge.js +22 -0
- package/dist/safety-hook.d.ts +79 -0
- package/dist/safety-hook.js +35 -0
- package/dist/stores/display-profile-store.d.ts +0 -1
- package/dist/stores/display-profile-store.js +0 -1
- package/dist/testing.d.ts +4 -0
- package/dist/testing.js +5 -0
- package/dist/transpile.js +124 -35
- package/dist/types.d.ts +13 -2
- package/dist/ui-hook.d.ts +0 -2
- package/dist/utils/cli.js +51 -3
- package/package.json +20 -5
- package/dist/api/shared/display-adapters/eink-mono.d.ts +0 -2
- package/dist/api/shared/display-adapters/eink-mono.js +0 -53
- package/dist/api/shared/display-adapters/ssd1309.d.ts +0 -2
- package/dist/api/shared/display-adapters/ssd1309.js +0 -136
- package/dist/api/shared/display-adapters/st7796.d.ts +0 -2
- package/dist/api/shared/display-adapters/st7796.js +0 -132
- package/dist/libdef/idf-discovery.d.ts +0 -7
- package/dist/libdef/idf-discovery.js +0 -59
- package/dist/licenses.d.ts +0 -185
- package/dist/licenses.js +0 -963
|
@@ -25,43 +25,13 @@ const RESISTIVE_TOUCH_LIBS = new Set([
|
|
|
25
25
|
"XPT2046_Touchscreen",
|
|
26
26
|
"Adafruit_TouchScreen",
|
|
27
27
|
]);
|
|
28
|
-
/** Default RGB565 scroll viewport canvas budget (~88 KB, ESP32-class SRAM). */
|
|
29
|
-
export const DEFAULT_SCROLL_CANVAS_BUDGET_BYTES = 88000;
|
|
30
|
-
/** PSRAM scroll canvas budget (~2 MB). ESP32-S3 with OPI/QSPI PSRAM exposes
|
|
31
|
-
* ~8 MB external RAM; a full-width scroll viewport canvas (e.g. 460×266×2 ≈
|
|
32
|
-
* 239 KB) is trivial there, so the transpile-time scroll-canvas-memory
|
|
33
|
-
* diagnostic should use a PSRAM-appropriate budget rather than the no-PSRAM
|
|
34
|
-
* SRAM default — otherwise every PSRAM target emits stale "exceeds budget"
|
|
35
|
-
* warnings for canvases the runtime allocates without issue. */
|
|
36
|
-
export const PSRAM_SCROLL_CANVAS_BUDGET_BYTES = 2_000_000;
|
|
37
|
-
/** Detect PSRAM from an Arduino FQBN buildTarget (e.g. "esp32:esp32:esp32s3:PSRAM=opi").
|
|
38
|
-
* Returns true for any PSRAM=<value> option whose value indicates PSRAM is
|
|
39
|
-
* enabled (opi, io, qspi, enabled, true). Returns false when absent or set
|
|
40
|
-
* to a disabled-looking value (disabled, false, none). */
|
|
41
|
-
export function buildTargetHasPsram(buildTarget) {
|
|
42
|
-
if (!buildTarget)
|
|
43
|
-
return false;
|
|
44
|
-
const opts = buildTarget.split(":");
|
|
45
|
-
for (const opt of opts) {
|
|
46
|
-
const eq = opt.indexOf("=");
|
|
47
|
-
if (eq < 0)
|
|
48
|
-
continue;
|
|
49
|
-
const key = opt.slice(0, eq).trim().toLowerCase();
|
|
50
|
-
const val = opt.slice(eq + 1).trim().toLowerCase();
|
|
51
|
-
if (key !== "psram")
|
|
52
|
-
continue;
|
|
53
|
-
// Any explicit PSRAM option except an explicit disabled value means PSRAM.
|
|
54
|
-
return !["disabled", "false", "none", "no", "0"].includes(val);
|
|
55
|
-
}
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
28
|
/**
|
|
59
29
|
* Resolve scroll config from a display profile. Declared overrides win;
|
|
60
30
|
* otherwise derive the input tier from the touch library (resistive chips →
|
|
61
31
|
* "resistive", any other touch → "capacitive", no touch → "none") and assume a
|
|
62
32
|
* full render tier (ESP32-class SRAM can fit a viewport canvas).
|
|
63
33
|
*/
|
|
64
|
-
export function resolveScrollConfig(display
|
|
34
|
+
export function resolveScrollConfig(display) {
|
|
65
35
|
const s = display.scroll ?? {};
|
|
66
36
|
const lib = display.touch && typeof display.touch === "object"
|
|
67
37
|
? display.touch.library
|
|
@@ -71,15 +41,6 @@ export function resolveScrollConfig(display, ctx) {
|
|
|
71
41
|
: display.touch
|
|
72
42
|
? "capacitive"
|
|
73
43
|
: "none";
|
|
74
|
-
// PSRAM-aware canvas budget: an explicit override always wins; otherwise use
|
|
75
|
-
// the PSRAM budget when the target opts into PSRAM — either via an explicit
|
|
76
|
-
// frameworkData.psram flag (IDF path) or an Arduino FQBN PSRAM= option — so
|
|
77
|
-
// the scroll-canvas-memory diagnostic doesn't emit stale warnings for canvases
|
|
78
|
-
// the runtime allocates in external RAM without issue. Else the SRAM default.
|
|
79
|
-
const psramBudget = ctx?.psram === true || buildTargetHasPsram(ctx?.buildTarget);
|
|
80
|
-
const budgetDefault = psramBudget
|
|
81
|
-
? PSRAM_SCROLL_CANVAS_BUDGET_BYTES
|
|
82
|
-
: DEFAULT_SCROLL_CANVAS_BUDGET_BYTES;
|
|
83
44
|
return {
|
|
84
45
|
inputTier: s.inputTier ?? derivedInput,
|
|
85
46
|
renderTier: s.renderTier ?? "full",
|
|
@@ -90,7 +51,6 @@ export function resolveScrollConfig(display, ctx) {
|
|
|
90
51
|
inputSmoothing: s.inputSmoothing ?? 0.3,
|
|
91
52
|
overrideProbes: s.overrideProbes ?? true,
|
|
92
53
|
debug: s.debug ?? false,
|
|
93
|
-
scrollCanvasBudgetBytes: s.scrollCanvasBudgetBytes ?? budgetDefault,
|
|
94
54
|
};
|
|
95
55
|
}
|
|
96
56
|
export function resolveDisplayProfile(config, registry) {
|
|
@@ -152,6 +112,8 @@ export function resolveDisplayProfile(config, registry) {
|
|
|
152
112
|
base.colorOrder = config.colorOrder;
|
|
153
113
|
if (config.invertDisplay !== undefined)
|
|
154
114
|
base.invertDisplay = config.invertDisplay;
|
|
115
|
+
if (config.scanlineSync !== undefined)
|
|
116
|
+
base.scanlineSync = config.scanlineSync;
|
|
155
117
|
if (config.touch === false)
|
|
156
118
|
base.touch = undefined;
|
|
157
119
|
else if (config.touch !== undefined)
|
|
@@ -179,13 +141,18 @@ export function resolveDisplayProfile(config, registry) {
|
|
|
179
141
|
}
|
|
180
142
|
/** Generate C++ code for a built-in touch library adapter.
|
|
181
143
|
*
|
|
182
|
-
* Strategy-owned touch adapters
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
144
|
+
* Strategy-owned touch adapters take precedence: when the strategy's
|
|
145
|
+
* `providesTouchAdapter()` returns true and `resolveTouchAdapter` returns
|
|
146
|
+
* non-null, that codegen wins. The Arduino-ecosystem libraries
|
|
147
|
+
* (XPT2046_Touchscreen, Adafruit_TouchScreen, Adafruit_STMPE610, FT6336U)
|
|
148
|
+
* are strategy-owned — they live in @typecad/framework-arduino
|
|
149
|
+
* (src/displays/touch-adapters-codegen.ts) and ArduinoStrategy dispatches to
|
|
150
|
+
* them. Cuttlefish keeps only the framework-agnostic `sdl` path here.
|
|
186
151
|
*
|
|
187
|
-
* Passing `undefined` for the strategy (or a strategy
|
|
188
|
-
*
|
|
152
|
+
* Passing `undefined` for the strategy (or a strategy whose
|
|
153
|
+
* resolveTouchAdapter returns undefined for the given library) falls through
|
|
154
|
+
* to the `sdl` branch below; any other library without a strategy-provided
|
|
155
|
+
* adapter throws.
|
|
189
156
|
*/
|
|
190
157
|
export function generateTouchAdapter(touch, strategy) {
|
|
191
158
|
if (strategy?.providesTouchAdapter?.() && strategy.resolveTouchAdapter) {
|
|
@@ -193,124 +160,6 @@ export function generateTouchAdapter(touch, strategy) {
|
|
|
193
160
|
if (code)
|
|
194
161
|
return code;
|
|
195
162
|
}
|
|
196
|
-
const cs = touch.cs ?? 0;
|
|
197
|
-
const irq = touch.irq;
|
|
198
|
-
if (touch.library === "XPT2046_Touchscreen") {
|
|
199
|
-
return {
|
|
200
|
-
includes: ["#include <XPT2046_Touchscreen.h>"],
|
|
201
|
-
declaration: `XPT2046_Touchscreen __tc_touch(${cs}${irq ? `, ${irq}` : ""});`,
|
|
202
|
-
functions: [
|
|
203
|
-
`static inline void touch_init() { __tc_touch.begin(); }`,
|
|
204
|
-
`static inline bool touch_isTouched() { return __tc_touch.touched(); }`,
|
|
205
|
-
`static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
|
|
206
|
-
` TS_Point __tp = __tc_touch.getPoint();`,
|
|
207
|
-
` if (x) *x = (int16_t)__tp.x;`,
|
|
208
|
-
` if (y) *y = (int16_t)__tp.y;`,
|
|
209
|
-
` if (z) *z = (int16_t)__tp.z;`,
|
|
210
|
-
`}`,
|
|
211
|
-
].join("\n"),
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
if (touch.library === "Adafruit_TouchScreen" && touch.analogPins) {
|
|
215
|
-
const a = touch.analogPins;
|
|
216
|
-
return {
|
|
217
|
-
includes: ["#include <TouchScreen.h>"],
|
|
218
|
-
declaration: `TouchScreen __tc_touch = TouchScreen(${a.xp}, ${a.yp}, ${a.xm}, ${a.ym}, ${a.rx});`,
|
|
219
|
-
functions: [
|
|
220
|
-
`static inline void touch_init() {}`,
|
|
221
|
-
`static inline bool touch_isTouched() { return __tc_touch.isTouching(); }`,
|
|
222
|
-
`static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
|
|
223
|
-
` TS_Point __tp = __tc_touch.getPoint();`,
|
|
224
|
-
` if (x) *x = (int16_t)__tp.x;`,
|
|
225
|
-
` if (y) *y = (int16_t)__tp.y;`,
|
|
226
|
-
` if (z) *z = (int16_t)__tp.z;`,
|
|
227
|
-
`}`,
|
|
228
|
-
].join("\n"),
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
if (touch.library === "Adafruit_STMPE610") {
|
|
232
|
-
return {
|
|
233
|
-
includes: ["#include <Adafruit_STMPE610.h>"],
|
|
234
|
-
declaration: `Adafruit_STMPE610 __tc_touch(${cs});`,
|
|
235
|
-
functions: [
|
|
236
|
-
`static inline void touch_init() { __tc_touch.begin(); }`,
|
|
237
|
-
`static inline bool touch_isTouched() { return __tc_touch.touched() && !__tc_touch.bufferEmpty(); }`,
|
|
238
|
-
`static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
|
|
239
|
-
` TS_Point __tp = __tc_touch.getPoint();`,
|
|
240
|
-
` if (x) *x = (int16_t)__tp.x;`,
|
|
241
|
-
` if (y) *y = (int16_t)__tp.y;`,
|
|
242
|
-
` if (z) *z = (int16_t)__tp.z;`,
|
|
243
|
-
`}`,
|
|
244
|
-
].join("\n"),
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
if (touch.library === "FT6336U") {
|
|
248
|
-
const addr = touch.i2cAddress ?? 0x38;
|
|
249
|
-
// I2C addresses are conventional in hex in Arduino code.
|
|
250
|
-
const addrHex = "0x" + addr.toString(16).toUpperCase();
|
|
251
|
-
const i2cFrequency = touch.i2cFrequency ?? 400000;
|
|
252
|
-
const reset = touch.resetPin;
|
|
253
|
-
const resetLines = reset
|
|
254
|
-
? [
|
|
255
|
-
` pinMode(${reset}, OUTPUT);`,
|
|
256
|
-
` digitalWrite(${reset}, LOW);`,
|
|
257
|
-
` delay(10);`,
|
|
258
|
-
` digitalWrite(${reset}, HIGH);`,
|
|
259
|
-
` delay(500);`,
|
|
260
|
-
].join("\n")
|
|
261
|
-
: ``;
|
|
262
|
-
return {
|
|
263
|
-
includes: ["#include <Wire.h>", "#include <RAK14014_FT6336U.h>"],
|
|
264
|
-
declaration: [
|
|
265
|
-
`FT6336U __tc_touch(${addrHex});`,
|
|
266
|
-
`static int16_t __tc_touch_cached_x = 0;`,
|
|
267
|
-
`static int16_t __tc_touch_cached_y = 0;`,
|
|
268
|
-
`static int16_t __tc_touch_cached_z = 0;`,
|
|
269
|
-
`static uint8_t __tc_touch_cached_valid = 0;`,
|
|
270
|
-
].join("\n"),
|
|
271
|
-
functions: [
|
|
272
|
-
`static inline uint8_t __tc_ft6336u_read_block(uint8_t reg, uint8_t* buf, uint8_t len) {`,
|
|
273
|
-
` Wire.beginTransmission(${addrHex});`,
|
|
274
|
-
` Wire.write(reg);`,
|
|
275
|
-
` if (Wire.endTransmission(false) != 0) return 0;`,
|
|
276
|
-
` uint8_t got = Wire.requestFrom((uint8_t)${addrHex}, len);`,
|
|
277
|
-
` if (got < len) return 0;`,
|
|
278
|
-
` for (uint8_t i = 0; i < len; i++) {`,
|
|
279
|
-
` if (!Wire.available()) return 0;`,
|
|
280
|
-
` buf[i] = Wire.read();`,
|
|
281
|
-
` }`,
|
|
282
|
-
` return 1;`,
|
|
283
|
-
`}`,
|
|
284
|
-
`static inline void touch_init() {`,
|
|
285
|
-
resetLines,
|
|
286
|
-
` __tc_touch.begin(Wire, ${addrHex});`,
|
|
287
|
-
` Wire.setClock(${i2cFrequency});`,
|
|
288
|
-
`}`,
|
|
289
|
-
`static inline bool touch_isTouched() {`,
|
|
290
|
-
` uint8_t buf[5] = {0, 0, 0, 0, 0};`,
|
|
291
|
-
` __tc_touch_cached_valid = 0;`,
|
|
292
|
-
` __tc_touch_cached_z = 0;`,
|
|
293
|
-
` if (!__tc_ft6336u_read_block(0x02, buf, 5)) return false;`,
|
|
294
|
-
` uint8_t count = buf[0] & 0x0F;`,
|
|
295
|
-
` if (count == 0) return false;`,
|
|
296
|
-
` __tc_touch_cached_x = (int16_t)(((uint16_t)(buf[1] & 0x0F) << 8) | buf[2]);`,
|
|
297
|
-
` __tc_touch_cached_y = (int16_t)(((uint16_t)(buf[3] & 0x0F) << 8) | buf[4]);`,
|
|
298
|
-
` __tc_touch_cached_z = 255;`,
|
|
299
|
-
` __tc_touch_cached_valid = 1;`,
|
|
300
|
-
` return true;`,
|
|
301
|
-
`}`,
|
|
302
|
-
`static inline void touch_readRaw(int16_t* x, int16_t* y, int16_t* z) {`,
|
|
303
|
-
` if (!__tc_touch_cached_valid) {`,
|
|
304
|
-
` (void)touch_isTouched();`,
|
|
305
|
-
` }`,
|
|
306
|
-
` if (x) *x = __tc_touch_cached_x;`,
|
|
307
|
-
` if (y) *y = __tc_touch_cached_y;`,
|
|
308
|
-
` if (z) *z = __tc_touch_cached_z;`,
|
|
309
|
-
` __tc_touch_cached_valid = 0;`,
|
|
310
|
-
`}`,
|
|
311
|
-
].join("\n"),
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
163
|
if (touch.library === "sdl") {
|
|
315
164
|
return {
|
|
316
165
|
includes: ["#include <SDL2/SDL.h>"],
|
|
@@ -340,14 +189,17 @@ export function generateTouchAdapter(touch, strategy) {
|
|
|
340
189
|
` int __ww = 0, __wh = 0; SDL_GetWindowSize(__tc_display.win, &__ww, &__wh);`,
|
|
341
190
|
` if (__ww <= 0) __ww = display_width();`,
|
|
342
191
|
` if (__wh <= 0) __wh = display_height();`,
|
|
343
|
-
` if (x) *x =
|
|
344
|
-
` if (y) *y =
|
|
192
|
+
` if (x) *x = static_cast<int16_t>(static_cast<int32_t>(__sdl_mouse_x) * display_width() / __ww);`,
|
|
193
|
+
` if (y) *y = static_cast<int16_t>(static_cast<int32_t>(__sdl_mouse_y) * display_height() / __wh);`,
|
|
345
194
|
` if (z) *z = 200; // constant > default minPressure (10)`,
|
|
346
195
|
`}`,
|
|
347
196
|
].join("\n"),
|
|
348
197
|
};
|
|
349
198
|
}
|
|
350
|
-
throw new Error(`
|
|
351
|
-
`
|
|
352
|
-
`
|
|
199
|
+
throw new Error(`No touch adapter for library "${touch.library}". ` +
|
|
200
|
+
`The built-in Arduino touch libraries (XPT2046_Touchscreen, Adafruit_TouchScreen, ` +
|
|
201
|
+
`Adafruit_STMPE610, FT6336U) are provided by @typecad/framework-arduino — pass the ` +
|
|
202
|
+
`ArduinoStrategy (or another framework strategy that provides touch adapters) so its ` +
|
|
203
|
+
`resolveTouchAdapter can dispatch to them. Otherwise use the framework-agnostic ` +
|
|
204
|
+
`"sdl" library, or { adapter: './path' } for a custom touch adapter.`);
|
|
353
205
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FrameworkManifest } from './framework-manifest.js';
|
|
2
|
-
export declare const KNOWN_FRAMEWORK_PACKAGES: readonly ["@typecad/framework-arduino", "@typecad/framework-
|
|
2
|
+
export declare const KNOWN_FRAMEWORK_PACKAGES: readonly ["@typecad/framework-arduino", "@typecad/framework-zephyr"];
|
|
3
3
|
export type KnownFrameworkPackage = typeof KNOWN_FRAMEWORK_PACKAGES[number];
|
|
4
4
|
/**
|
|
5
5
|
* Loads a framework's manifest via its `./framework.manifest` subpath export.
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
// ---------------------------------------------------------------------------
|
|
2
2
|
// Framework manifest discovery
|
|
3
3
|
//
|
|
4
|
-
// KNOWN_FRAMEWORK_PACKAGES is the authoritative list of framework packages
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
4
|
+
// KNOWN_FRAMEWORK_PACKAGES is the authoritative list of framework packages
|
|
5
|
+
// that ship a framework.manifest (i.e. participate in the manifest validation
|
|
6
|
+
// system). It names real packages by their npm scope+name so the manifest
|
|
7
|
+
// validator and coverage tooling can iterate them — it is not framework-
|
|
8
|
+
// specific knowledge. Add a new framework here when it ships a manifest.
|
|
9
|
+
// loadFrameworkManifest uses the "./framework.manifest" subpath export each
|
|
10
|
+
// framework declares in its package.json.
|
|
8
11
|
// ---------------------------------------------------------------------------
|
|
9
12
|
export const KNOWN_FRAMEWORK_PACKAGES = [
|
|
10
13
|
'@typecad/framework-arduino',
|
|
11
|
-
'@typecad/framework-
|
|
12
|
-
'@typecad/framework-esp32',
|
|
14
|
+
'@typecad/framework-zephyr',
|
|
13
15
|
];
|
|
14
16
|
/**
|
|
15
17
|
* Loads a framework's manifest via its `./framework.manifest` subpath export.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
declare const HAL_CATEGORIES: readonly ["gpio", "pwm", "adc", "dac", "interrupts", "tone", "timing", "power", "i2c", "spi", "uart", "pulse", "shift", "board", "wdt", "wifi", "http", "display"];
|
|
2
|
+
declare const HAL_CATEGORIES: readonly ["gpio", "pwm", "adc", "dac", "interrupts", "tone", "timing", "power", "i2c", "spi", "uart", "pulse", "shift", "board", "wdt", "wifi", "http", "mqtt", "display"];
|
|
3
3
|
export type HalCategory = typeof HAL_CATEGORIES[number];
|
|
4
4
|
export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
5
5
|
schemaVersion: z.ZodLiteral<1>;
|
|
@@ -74,23 +74,102 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
|
74
74
|
}, {
|
|
75
75
|
supported: boolean;
|
|
76
76
|
}>>;
|
|
77
|
+
}, "strip", z.ZodObject<{
|
|
78
|
+
supported: z.ZodBoolean;
|
|
79
|
+
unsupportedReason: z.ZodOptional<z.ZodString>;
|
|
80
|
+
ops: z.ZodRecord<z.ZodString, z.ZodEnum<["supported", "stub", "unsupported", "probe-inconclusive", "polyfill"]>>;
|
|
81
|
+
partialCoverage: z.ZodDefault<z.ZodBoolean>;
|
|
77
82
|
}, "strip", z.ZodTypeAny, {
|
|
78
|
-
|
|
83
|
+
supported: boolean;
|
|
84
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
85
|
+
partialCoverage: boolean;
|
|
86
|
+
unsupportedReason?: string | undefined;
|
|
87
|
+
}, {
|
|
88
|
+
supported: boolean;
|
|
89
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
90
|
+
unsupportedReason?: string | undefined;
|
|
91
|
+
partialCoverage?: boolean | undefined;
|
|
92
|
+
}>, z.objectOutputType<{
|
|
93
|
+
[x: string]: z.ZodObject<{
|
|
94
|
+
supported: z.ZodBoolean;
|
|
95
|
+
unsupportedReason: z.ZodOptional<z.ZodString>;
|
|
96
|
+
ops: z.ZodRecord<z.ZodString, z.ZodEnum<["supported", "stub", "unsupported", "probe-inconclusive", "polyfill"]>>;
|
|
97
|
+
partialCoverage: z.ZodDefault<z.ZodBoolean>;
|
|
98
|
+
}, "strip", z.ZodTypeAny, {
|
|
79
99
|
supported: boolean;
|
|
80
100
|
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
81
101
|
partialCoverage: boolean;
|
|
82
102
|
unsupportedReason?: string | undefined;
|
|
83
|
-
}
|
|
84
|
-
|
|
103
|
+
}, {
|
|
104
|
+
supported: boolean;
|
|
105
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
106
|
+
unsupportedReason?: string | undefined;
|
|
107
|
+
partialCoverage?: boolean | undefined;
|
|
108
|
+
}>;
|
|
109
|
+
} & {
|
|
110
|
+
raw: z.ZodDefault<z.ZodObject<{
|
|
111
|
+
supported: z.ZodBoolean;
|
|
112
|
+
}, "strip", z.ZodTypeAny, {
|
|
113
|
+
supported: boolean;
|
|
114
|
+
}, {
|
|
115
|
+
supported: boolean;
|
|
116
|
+
}>>;
|
|
117
|
+
}, z.ZodObject<{
|
|
118
|
+
supported: z.ZodBoolean;
|
|
119
|
+
unsupportedReason: z.ZodOptional<z.ZodString>;
|
|
120
|
+
ops: z.ZodRecord<z.ZodString, z.ZodEnum<["supported", "stub", "unsupported", "probe-inconclusive", "polyfill"]>>;
|
|
121
|
+
partialCoverage: z.ZodDefault<z.ZodBoolean>;
|
|
122
|
+
}, "strip", z.ZodTypeAny, {
|
|
123
|
+
supported: boolean;
|
|
124
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
125
|
+
partialCoverage: boolean;
|
|
126
|
+
unsupportedReason?: string | undefined;
|
|
85
127
|
}, {
|
|
86
|
-
|
|
128
|
+
supported: boolean;
|
|
129
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
130
|
+
unsupportedReason?: string | undefined;
|
|
131
|
+
partialCoverage?: boolean | undefined;
|
|
132
|
+
}>, "strip">, z.objectInputType<{
|
|
133
|
+
[x: string]: z.ZodObject<{
|
|
134
|
+
supported: z.ZodBoolean;
|
|
135
|
+
unsupportedReason: z.ZodOptional<z.ZodString>;
|
|
136
|
+
ops: z.ZodRecord<z.ZodString, z.ZodEnum<["supported", "stub", "unsupported", "probe-inconclusive", "polyfill"]>>;
|
|
137
|
+
partialCoverage: z.ZodDefault<z.ZodBoolean>;
|
|
138
|
+
}, "strip", z.ZodTypeAny, {
|
|
139
|
+
supported: boolean;
|
|
140
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
141
|
+
partialCoverage: boolean;
|
|
142
|
+
unsupportedReason?: string | undefined;
|
|
143
|
+
}, {
|
|
87
144
|
supported: boolean;
|
|
88
145
|
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
89
146
|
unsupportedReason?: string | undefined;
|
|
90
147
|
partialCoverage?: boolean | undefined;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
148
|
+
}>;
|
|
149
|
+
} & {
|
|
150
|
+
raw: z.ZodDefault<z.ZodObject<{
|
|
151
|
+
supported: z.ZodBoolean;
|
|
152
|
+
}, "strip", z.ZodTypeAny, {
|
|
153
|
+
supported: boolean;
|
|
154
|
+
}, {
|
|
155
|
+
supported: boolean;
|
|
156
|
+
}>>;
|
|
157
|
+
}, z.ZodObject<{
|
|
158
|
+
supported: z.ZodBoolean;
|
|
159
|
+
unsupportedReason: z.ZodOptional<z.ZodString>;
|
|
160
|
+
ops: z.ZodRecord<z.ZodString, z.ZodEnum<["supported", "stub", "unsupported", "probe-inconclusive", "polyfill"]>>;
|
|
161
|
+
partialCoverage: z.ZodDefault<z.ZodBoolean>;
|
|
162
|
+
}, "strip", z.ZodTypeAny, {
|
|
163
|
+
supported: boolean;
|
|
164
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
165
|
+
partialCoverage: boolean;
|
|
166
|
+
unsupportedReason?: string | undefined;
|
|
167
|
+
}, {
|
|
168
|
+
supported: boolean;
|
|
169
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
170
|
+
unsupportedReason?: string | undefined;
|
|
171
|
+
partialCoverage?: boolean | undefined;
|
|
172
|
+
}>, "strip">>;
|
|
94
173
|
polyfills: z.ZodObject<{
|
|
95
174
|
emitted: z.ZodArray<z.ZodObject<{
|
|
96
175
|
id: z.ZodString;
|
|
@@ -269,10 +348,40 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
|
269
348
|
hardwareTestGroups: string[];
|
|
270
349
|
halResolutionTests: string[];
|
|
271
350
|
}>;
|
|
351
|
+
doctor: z.ZodOptional<z.ZodObject<{
|
|
352
|
+
available: z.ZodBoolean;
|
|
353
|
+
}, "strip", z.ZodTypeAny, {
|
|
354
|
+
available: boolean;
|
|
355
|
+
}, {
|
|
356
|
+
available: boolean;
|
|
357
|
+
}>>;
|
|
358
|
+
licenses: z.ZodOptional<z.ZodObject<{
|
|
359
|
+
available: z.ZodBoolean;
|
|
360
|
+
}, "strip", z.ZodTypeAny, {
|
|
361
|
+
available: boolean;
|
|
362
|
+
}, {
|
|
363
|
+
available: boolean;
|
|
364
|
+
}>>;
|
|
272
365
|
}, "strip", z.ZodTypeAny, {
|
|
366
|
+
hal: {
|
|
367
|
+
[x: string]: {
|
|
368
|
+
supported: boolean;
|
|
369
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
370
|
+
partialCoverage: boolean;
|
|
371
|
+
unsupportedReason?: string | undefined;
|
|
372
|
+
};
|
|
373
|
+
raw?: unknown;
|
|
374
|
+
} & {
|
|
375
|
+
[k: string]: {
|
|
376
|
+
supported: boolean;
|
|
377
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
378
|
+
partialCoverage: boolean;
|
|
379
|
+
unsupportedReason?: string | undefined;
|
|
380
|
+
};
|
|
381
|
+
};
|
|
382
|
+
packageName: string;
|
|
273
383
|
schemaVersion: 1;
|
|
274
384
|
frameworkId: string;
|
|
275
|
-
packageName: string;
|
|
276
385
|
canonical: boolean;
|
|
277
386
|
displayName: string;
|
|
278
387
|
description: string;
|
|
@@ -291,15 +400,6 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
|
291
400
|
symbolAliases: Record<string, string>;
|
|
292
401
|
targets: string[];
|
|
293
402
|
};
|
|
294
|
-
hal: {
|
|
295
|
-
[x: string]: {
|
|
296
|
-
supported: boolean;
|
|
297
|
-
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
298
|
-
partialCoverage: boolean;
|
|
299
|
-
unsupportedReason?: string | undefined;
|
|
300
|
-
};
|
|
301
|
-
raw?: unknown;
|
|
302
|
-
};
|
|
303
403
|
polyfills: {
|
|
304
404
|
emitted: {
|
|
305
405
|
id: string;
|
|
@@ -343,6 +443,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
|
343
443
|
hardwareTestGroups: string[];
|
|
344
444
|
halResolutionTests: string[];
|
|
345
445
|
};
|
|
446
|
+
doctor?: {
|
|
447
|
+
available: boolean;
|
|
448
|
+
} | undefined;
|
|
449
|
+
licenses?: {
|
|
450
|
+
available: boolean;
|
|
451
|
+
} | undefined;
|
|
346
452
|
basedOn?: string | undefined;
|
|
347
453
|
inheritsStrategyId?: string | undefined;
|
|
348
454
|
libraryResolution?: {
|
|
@@ -353,9 +459,25 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
|
353
459
|
reexportedFrom?: string | undefined;
|
|
354
460
|
} | undefined;
|
|
355
461
|
}, {
|
|
462
|
+
hal: {
|
|
463
|
+
[x: string]: {
|
|
464
|
+
supported: boolean;
|
|
465
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
466
|
+
unsupportedReason?: string | undefined;
|
|
467
|
+
partialCoverage?: boolean | undefined;
|
|
468
|
+
};
|
|
469
|
+
raw?: unknown;
|
|
470
|
+
} & {
|
|
471
|
+
[k: string]: {
|
|
472
|
+
supported: boolean;
|
|
473
|
+
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
474
|
+
unsupportedReason?: string | undefined;
|
|
475
|
+
partialCoverage?: boolean | undefined;
|
|
476
|
+
};
|
|
477
|
+
};
|
|
478
|
+
packageName: string;
|
|
356
479
|
schemaVersion: 1;
|
|
357
480
|
frameworkId: string;
|
|
358
|
-
packageName: string;
|
|
359
481
|
displayName: string;
|
|
360
482
|
description: string;
|
|
361
483
|
implementationMode: "from-scratch" | "extends-canonical" | "extends-other";
|
|
@@ -373,15 +495,6 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
|
373
495
|
symbolAliases: Record<string, string>;
|
|
374
496
|
targets: string[];
|
|
375
497
|
};
|
|
376
|
-
hal: {
|
|
377
|
-
[x: string]: {
|
|
378
|
-
supported: boolean;
|
|
379
|
-
ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
|
|
380
|
-
unsupportedReason?: string | undefined;
|
|
381
|
-
partialCoverage?: boolean | undefined;
|
|
382
|
-
};
|
|
383
|
-
raw?: unknown;
|
|
384
|
-
};
|
|
385
498
|
polyfills: {
|
|
386
499
|
emitted: {
|
|
387
500
|
id: string;
|
|
@@ -425,6 +538,12 @@ export declare const FrameworkManifestSchema: z.ZodObject<{
|
|
|
425
538
|
hardwareTestGroups: string[];
|
|
426
539
|
halResolutionTests: string[];
|
|
427
540
|
};
|
|
541
|
+
doctor?: {
|
|
542
|
+
available: boolean;
|
|
543
|
+
} | undefined;
|
|
544
|
+
licenses?: {
|
|
545
|
+
available: boolean;
|
|
546
|
+
} | undefined;
|
|
428
547
|
canonical?: boolean | undefined;
|
|
429
548
|
basedOn?: string | undefined;
|
|
430
549
|
inheritsStrategyId?: string | undefined;
|
|
@@ -11,10 +11,21 @@
|
|
|
11
11
|
// cross-checks each claim against the loaded strategy/toolchain.
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
import { z } from 'zod';
|
|
14
|
+
// Core HAL categories that EVERY framework MUST declare coverage for (the
|
|
15
|
+
// universal embedded surface: digital/analog I/O, comms buses, timing, power,
|
|
16
|
+
// watchdog). These keys are required in every manifest's `hal` block.
|
|
17
|
+
//
|
|
18
|
+
// Extended categories — `rmt`, `ble`, `preferences`, `random`, `fs`, `mqtt`,
|
|
19
|
+
// `mdns`, `ota`, etc. — are OPTIONAL: a framework declares them only if it
|
|
20
|
+
// lowers them. The HalCoverageSchema below uses `.catchall()` so declared
|
|
21
|
+
// extended categories survive zod parsing (they used to be silently stripped,
|
|
22
|
+
// which made esp32's ble/rmt/preferences manifest blocks dead data) and get
|
|
23
|
+
// validated by the manifest validator like any core category. A framework that
|
|
24
|
+
// does not lower an extended category simply omits it.
|
|
14
25
|
const HAL_CATEGORIES = [
|
|
15
26
|
'gpio', 'pwm', 'adc', 'dac', 'interrupts', 'tone', 'timing', 'power',
|
|
16
27
|
'i2c', 'spi', 'uart', 'pulse', 'shift', 'board', 'wdt', 'wifi', 'http',
|
|
17
|
-
'display',
|
|
28
|
+
'mqtt', 'display',
|
|
18
29
|
];
|
|
19
30
|
const OpStatus = z.enum(['supported', 'stub', 'unsupported', 'probe-inconclusive', 'polyfill']);
|
|
20
31
|
const HalCategorySchema = z.object({
|
|
@@ -32,7 +43,15 @@ const HalCoverageSchema = z.object(Object.fromEntries(HAL_CATEGORIES.map((c) =>
|
|
|
32
43
|
c === 'display' ? DisplayCategorySchema : HalCategorySchema,
|
|
33
44
|
]))).extend({
|
|
34
45
|
raw: z.object({ supported: z.boolean() }).default({ supported: true }),
|
|
35
|
-
|
|
46
|
+
// catchall: extended categories (rmt, ble, preferences, random, fs, mqtt,
|
|
47
|
+
// mdns, ota, ...) declared by a framework that lowers them. Without this,
|
|
48
|
+
// zod's default object parsing silently strips unknown keys, so a manifest's
|
|
49
|
+
// `ble:` / `rmt:` / `preferences:` / `random:` blocks never reached the
|
|
50
|
+
// validator or consumers. The catchall validates them with the same shape as
|
|
51
|
+
// core categories (HalCategorySchema) and preserves them on the parsed
|
|
52
|
+
// object. Frameworks that don't lower an extended category simply omit it.
|
|
53
|
+
// `raw` is excluded — it is the escape hatch, not a HAL category.
|
|
54
|
+
}).catchall(HalCategorySchema);
|
|
36
55
|
const EntrypointSchema = z.object({
|
|
37
56
|
entrypointFunctionName: z.string(),
|
|
38
57
|
requiresLoopFunction: z.boolean(),
|
|
@@ -75,6 +94,15 @@ const LibraryResolutionSchema = z.object({
|
|
|
75
94
|
tryGenerateLibDecl: z.boolean(),
|
|
76
95
|
reexportedFrom: z.string().optional(),
|
|
77
96
|
});
|
|
97
|
+
/**
|
|
98
|
+
* Capability block for an optional subcommand the framework may own (e.g.
|
|
99
|
+
* `cuttlefish doctor`, `cuttlefish licenses`). The manifest only declares
|
|
100
|
+
* availability; the framework's runtime `doctor` / `licenses` exports provide
|
|
101
|
+
* the implementation, and cuttlefish dispatches to them when present.
|
|
102
|
+
*/
|
|
103
|
+
const SubcommandCapabilitySchema = z.object({
|
|
104
|
+
available: z.boolean(),
|
|
105
|
+
});
|
|
78
106
|
const StdLibSupportSchema = z.object({
|
|
79
107
|
hasVector: z.boolean(),
|
|
80
108
|
hasString: z.boolean(),
|
|
@@ -116,6 +144,11 @@ export const FrameworkManifestSchema = z.object({
|
|
|
116
144
|
typeEmission: TypeEmissionSchema,
|
|
117
145
|
ambientTypes: z.array(z.string()),
|
|
118
146
|
conformance: ConformanceSchema,
|
|
147
|
+
// Optional subcommand capabilities owned by the framework. When declared
|
|
148
|
+
// `{ available: true }`, the framework exports matching `doctor` / `licenses`
|
|
149
|
+
// functions that cuttlefish dispatches the corresponding CLI subcommands to.
|
|
150
|
+
doctor: SubcommandCapabilitySchema.optional(),
|
|
151
|
+
licenses: SubcommandCapabilitySchema.optional(),
|
|
119
152
|
});
|
|
120
153
|
/**
|
|
121
154
|
* Authoritative map of HAL op kinds that are lowered via the polyfill system
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DisplayHALOp } from "./display-op-ir.js";
|
|
2
|
-
import type { ResolvedDisplay, TouchProfile, TouchAdapterCodegen } from "./display-profile.js";
|
|
2
|
+
import type { DisplayProfile, ResolvedDisplay, TouchProfile, TouchAdapterCodegen } from "./display-profile.js";
|
|
3
3
|
import type { DisplayAdapterCode } from "./display-adapter.js";
|
|
4
4
|
export interface GraphicsCapacity {
|
|
5
5
|
/** Max nodes the retained tree may hold on this target. */
|
|
@@ -18,14 +18,15 @@ export interface PlatformGraphicsStrategy {
|
|
|
18
18
|
expression?: string;
|
|
19
19
|
} | undefined;
|
|
20
20
|
/**
|
|
21
|
-
* True if this strategy emits its own display adapters (
|
|
22
|
-
*
|
|
23
|
-
*
|
|
21
|
+
* True if this strategy emits its own display adapters (e.g. framework-arduino
|
|
22
|
+
* owns the Adafruit_GFX drivers, framework-native owns SDL). When false or
|
|
23
|
+
* undefined, generateDisplayAdapter() falls back to cuttlefish's generic
|
|
24
|
+
* built-in adapter registry.
|
|
24
25
|
*/
|
|
25
26
|
providesDisplayAdapter?(): boolean;
|
|
26
27
|
/**
|
|
27
|
-
* Returns the adapter code for one display, or undefined to defer to
|
|
28
|
-
* built-in
|
|
28
|
+
* Returns the adapter code for one display, or undefined to defer to cuttlefish's
|
|
29
|
+
* built-in adapter registry. Only called when providesDisplayAdapter()
|
|
29
30
|
* returns true.
|
|
30
31
|
*/
|
|
31
32
|
resolveDisplayAdapter?(display: ResolvedDisplay): DisplayAdapterCode | undefined;
|
|
@@ -43,6 +44,14 @@ export interface PlatformGraphicsStrategy {
|
|
|
43
44
|
* surface a clear compile-time error instead of emitting incompatible code.
|
|
44
45
|
*/
|
|
45
46
|
resolveTouchAdapter?(touch: TouchProfile): TouchAdapterCodegen | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Optional hook returning this framework's named display-profile registry
|
|
49
|
+
* (profile name → DisplayProfile). When present, transpile.ts consults it to
|
|
50
|
+
* resolve `display.profile` config values instead of dynamically importing a
|
|
51
|
+
* framework module — so profile names resolve correctly per-framework.
|
|
52
|
+
* Returns undefined to fall back to the legacy dynamic-import path.
|
|
53
|
+
*/
|
|
54
|
+
getProfileRegistry?(): Map<string, DisplayProfile>;
|
|
46
55
|
/** Display driver ids this framework provides (e.g. new Set(["ili9341"])). */
|
|
47
56
|
supportedDisplayDrivers(): ReadonlySet<string>;
|
|
48
57
|
/** Target color format — drives transpile-time color resolution.
|