Commit graph pcbjam/wasm/stubs
Author SHA1 Message Date
Istvan Matejcsok
c421d724b0 findings(E-10..E-22): fix the defects a code review found in the E-1..E-9 work
A review of the group-E fixes found 13 further defects; ten were introduced by
those fixes, two pre-existed and were merely relocated, one is deferred.

Services / transport
  E-10  retireWorker synthesized no bg/exit frame, so sharedspice's s_bgRunning
        mirror stayed latched true after a mid-run worker death: Run stayed
        disabled and the promised fresh-worker restart was unreachable for the
        whole session. Retirement now dispatches a synthetic controlled-exit
        straight to the installed handler (never through dispatchEvt — a
        fabricated frame must not touch the credit ledger). Driving the repro
        exposed two further defects, both fixed here: a replacement worker
        trapped on pre-init engine reads, and the rerun's cm_input_path/circ hit
        that uninitialized engine before KiCad's validate() re-init (the native
        flow assumes a crashed engine survives in-process — true for the dll,
        false for a dead worker). Reads now answer their empty shapes pre-init,
        writes lazy-init, and init is idempotent per worker engine.
  E-19  dispatchEvt acked only AFTER handler(evt) returned, and the sharedspice
        client deliberately rethrows non-trap errors — so each throw leaked one
        unit of the 64-frame credit window until the stream died with a
        misattributed "transport exceeded". The ack moves to a finally in both
        service copies; the throw still propagates (the trap machinery needs it).
  E-20  the oversize-line path promises to transfer the accepted prefix, but
        with the window full that flush only DEFERS, and stopEventStream wiped
        the deferred queue — losing the diagnostics that explain the failure.
        The terminal notice now carries them as pendingEvents; both hosts
        deliver them in order, unacked (the fatal frame is outside the credit
        protocol).
  E-21  the 30s prefetch deadline discarded every model already collected and
        reported nothing. A caller-owned progress sink ships the partials and
        the omission reaches the export report. (Awaiting the aborted collection
        was rejected: an in-flight source fetch is not abortable — E-4's
        original disease.) Plus a serving-candidate memo, so a .wrl ref served
        by its .step fallback stops re-probing the miss on every export.

Scheduler
  E-14  _terminalizeNativeTrap classified by message substring, so any plain JS
        error QUOTING 'Aborted(' or 'out of bounds' permanently bricked a
        healthy instance. Now structural only: instanceof RuntimeError plus a
        duck-typed name check (verified in this build's glue that abort() throws
        a genuine RuntimeError both pre- and post-runtime-init). Module.onAbort
        now latches the gate — the authoritative notification, previously
        ignored.
  E-15  the shim half: _pumpResume gates on terminal (catching wakes already
        queued at latch time) and resolveWait refuses on terminal WITHOUT
        consuming the entry, so a frame stays visibly parked rather than
        resuming inside a trapped module.
  E-16  the E-5 handler read the realm-global scheduler at dispatch instead of
        its installing module's; also frees the per-line buffer on the non-trap
        rethrow path.
  E-11  get_vec trusted the worker's res.length over the transferred arrays.
        Observed death shape: a 4 GiB std::vector threw an unhandled
        std::length_error that exited the editor's main loop. Now clamped, with
        the buffers freed on every failure path.

Guardrails (replacing two deferred refactors: e2e→production-code injection and
collapsing the four copies of the worker-lifecycle machinery)
  E-18  the source contract asserted comment-string counts — rewording failed
        CI while moving a guard outside its #ifdef passed. It now parses the
        #ifdef regions and asserts on code.
        service-stub-parity.ts pins what the four lifecycle copies must share:
        credit-window equality parsed from source, the finally-ack, boot
        deadlines, terminal-notice consumption. The transport numbers are now
        single-sourced from the worker.
        CI actually runs the gates: the web/standalone vitest suites (which had
        NEVER run in CI), the reducer, the source contract and the parity tool —
        with a NON_PLAYWRIGHT_GATES check so deleting a step re-fails the lint.
  E-22  the e2e occ stub's 60s boot watchdog, deleted in a66e109, is restored in
        the ngspice-stub shape with a wedgeNextBoot() repro hook.

Every behavioral fix has red-then-green evidence (the reds were captured first).
E-17 (a stale RUNNING cross-stamping the next run's generation under E-6's
transport deferral) is DEFERRED with its analysis recorded — a real fix needs
run identity on the bg frames.

Test hygiene: the dwell lint now requires the mandated ": <why>" and all 47 bare
markers carry their reason; three export-report dwells became modal-lease polls;
exact-ledger assertions became relative deltas; the dead data-wx-dom-id branch,
an unused fault hook and unused receipt plumbing are gone; abort scans, wx
dialog drivers, the sim harness and the vitest FakeWorker are each one copy now.

Bumps kicad and wxwidgets to their findings-group-e tips.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-31 18:19:16 +02:00
Istvan Matejcsok
06a46546cc findings(E-5,E-6): validation-round fixes — live e2e falsified two ported shapes
E-5: the module-identity bridge called installingModule._malloc, but this
build exposes _malloc only as a bare glue-closure export (Module._malloc is
absent) — every char/stat event entry threw TypeError, which also starved
the E-6 credit window (thrown dispatches never acked) and wedged the queued
bg-finished frame behind them. The bridge now uses the bare closure exports
(identity is still exact: the EM_JS body IS the installing module's closure;
the __ngspiceOnEvent self-disarm covers supersession).

E-6 (codex reference design corrected — its validation matrix never ran):
a FULL credit window was terminal (stopEventStream at 64 in-flight frames).
Under live e2e that killed a real simulation: bg-thread emissions proxy one
per task, so each line ships as its own frame and a normal transient outruns
a busy main thread. A full window now DEFERS into a bounded FIFO (512 events
/ 4 MiB) drained in order as acks free credit; only true overload or an
invalid ack is terminal. Retention stays bounded (8 MiB in flight + 4 MiB
deferred + 1 MiB open batch). And the service/harness mirror queue now acks
at ENQUEUE — placing a frame in the bounded pre-handler queue is taking
ownership; without that, a stream starting before the C++ handler installs
(the ngspice-probe page) starves the worker window forever.

Test updates: worker-batch reducer — new "a full credit window defers and
drains in order, never terminal" case pinning the regression; the storm case
now proves the deferred caps are the terminal edge. board-ready.ts gains the
owner-free openBoardProgrammatically (codex helper the ported occ-export
spec needs; the barrier-based waitForUiBoardReady was NOT taken).
occ-export.spec: domId is optional on this line's registry (coordinate
fallback is the supported path).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 18:18:21 +02:00
Istvan Matejcsok
c14e76651c findings(E-5,E-8,E-9): module-identity ngspice events + runWaitCompletion admission gate
E-8 (re-implemented for JSPI — the codex gate is entangled with the dropped
execution owner; under JSPI a fresh non-suspending JS→wasm entry while
another activation is suspended is structurally safe on its own stack, so
the admission boundary for worker completions is liveness + trap state, not
execution ownership):
- jspi-scheduler.js grows `terminal` (trapped instance; distinct from `dead`),
  canTouchNative(), _terminalizeNativeTrap() (WebAssembly.RuntimeError +
  cross-realm string classification), and runWaitCompletion(site, token,
  prepare, inertResult): prepare runs immediately and owns ALL native work;
  stale tokens and dead/terminal instances drop loudly without resolving
  (resolving would resume the parked frame inside the damaged module); a
  trap latches terminal; a plain JS bug resolves inertResult so the wait
  fails instead of stranding. beginWait refuses (token 0) when dead/terminal.
- all four delayed completion sites route their native work through the
  gate: 'OCC export completion' (exporter_step_stub), 'OCC model completion'
  (oce_plugin_stub — the MEMFS cache write moves inside the gate too),
  'ngspice request completion' and 'ngspice vector completion'
  (sharedspice_client — every HEAP32/HEAPF64/malloc write inside prepare,
  inertResult 1 = transport error). Every wxWasmBeginWait caller in the
  stubs bails on token <= 0.
- deliberately NOT ported from codex: ownerModule, enqueueNativeCompletion,
  executionBarrier, the byte-credit native-entry FIFO — completions are
  one-shot per wait token and stream volume is bounded at the E-6 transport
  credit window. Cross-refs logged for group M (M-2/M-6/M-8).

E-5 (re-implemented; codex shape kept, owner APIs replaced with the E-8
gate): js_ngspice_install_events binds the handler to the EXACT installing
module (handler.__pcbjamNgspiceOwnerModule stamp; presence is not identity),
re-installation replaces a foreign module's handler, a superseded handler
disarms itself, native entry goes through installingModule._malloc/
._pcbjam_ngspice_event (never lexical Module), each dispatch checks
canTouchNative() (loud drop on a dead/terminal module), and a trap on the
per-line entry latches the terminal gate.

Tests: scheduler-shim.test.ts +7 (gate happy/stale/dead/terminal/cross-realm/
js-bug/beginWait-refusal). e2e specs updated from the codex line: occ-export
decode-fault recovery (real onmessageerror transition via failDecode, J-4),
ngspice-probe direct-service coverage, eeschema-sim rewritten onto the E-7
applied-generation receipt (codex's executionBarrier await replaced with a
pendingWaits('ngspice') drain poll — the JSPI-line equivalent).

Also bumps the kicad submodule to the E-7/E-9 commit (dd5751038f7).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-31 18:18:21 +02:00
Viktor Vaczi
9c475a804e jspi cleanup: remove the asyncify-era residue — dead code, conditionals, pipeline scaffolding, stale prose
The runtime is JSPI-only; this removes everything that still pretended
otherwise. Three exhaustive sweeps (C++/JS+build+CI/tests+docs) drove
the inventory; every deletion verified by grep closure + full gates.

Broken-right-now fixes:
- deploy-staging.yml passed the retired opt_level input — the workflow
  could not even start. Removed.
- env.sh carried dead exports with a live -sASYNCIFY=1 inside
  (WASM_LDFLAGS/PTHREAD_LDFLAGS, zero consumers). Removed; the
  WASM_LEGACY_EXCEPTIONS rationale rewritten to the real reason.
- docker/build.sh exported PCBJAM_ASYNC_BACKEND (read nowhere). Gone.

Dead weight removed:
- binaryen submodule (nothing builds or invokes it), wasm-opt-bench
  workflow + scripts/bench/, get-wasm-opt.sh, diagnostics.js (242 lines
  of Asyncify-API-only code), the KICAD_PIPELINE background-postprocess
  scaffolding (existed to parallelize the deleted wasm-opt phase; the
  postprocess is a seconds-long node script and now runs inline),
  build-monitor's dead asyncify rows, sched-context orphan build
  output, dead .gitignore entries, the .jspi-assets spike dir (the two
  wf-result research JSONs moved to docs/features/async/migration-evidence/).
- bindings: fiber_park.h + its 12 embind registrations (broken-if-
  called under JSPI), the kicadOpenFileStart/OPEN_JOB starter route,
  main_stack_runner.h + 5 includes, the always-null context-sleep weak
  hook in nanosleep_yield.c.
- shim: the backend field (installed-flag idempotency instead),
  noteContextWait (dead both sides), the __wxAsyncifyDump alias (+ the
  WasmTool fallback and string-dump normalize branch).
- web: the emscripten-6-ignored mainScriptUrlOrBlob option in boot.ts
  (gerber-demo keeps it: it loads the deployed CDN release, which
  predates emscripten 6 — noted inline).

Conditionals: all 'backend === jspi' checks reduced to scheduler-
presence checks; races_quiescent re-keyed from Asyncify.state (vacuous)
to real backlog quiescence (resumeReady/mutatorQueue — NOT _windowLive,
which is the probing activation's own window by definition).

Renames (identifiers only, no file renames): ASYNC_LINK_FLAGS→
JSPI_LINK_FLAGS and Makefile ASYNC_LDFLAGS→JSPI_LDFLAGS,
kicadCollabFiberBusy→kicadCollabBusy (embind + web + tests),
collab_common.h fiber*→apply*/coroutine naming, asyncifySignatures→
wasmTrapSignatures (lists byte-identical).

Tests: the two remaining vacuous [wx-asyncify]/fiber-resume-refused
asserts re-keyed to live JSPI beacons; eeschema-load's failure message
no longer sends the developer to a deleted script; wait-beacons' dead
families/parser deleted; lane-0 legacy-glue guards removed (lane 0 is
unconstructible); the embind test.fail re-gated with the JSPI reason
(plain embind invokers cannot suspend — verified still failing);
lint-determinism now scans tests/jspi (166 files clean);
eeschema-collab local-move gated to chromium (~50% flaky on FF even
solo; pcbnew twin covers both engines).

Docs: DEBUG.md rewritten as the JSPI debugging guide; build.md
describes the single-phase build; docs/features/async/README.md
banner-marked historical and repointed at the NEW
23-jspi-runtime.md (current architecture: export census, turnstile,
libcontext ownership + refusal contract, embind call shapes, the
em-pthread service-wrapper trick, exception policy, known gaps).

Gates on the cleaned tree: test:e2e 725 passed / 0 failed (after the
quiescence-probe fix; the 3 other reds were verified contention flakes
solo-green or the documented FF gate), web 76/0, jspi 18/18 both
engines, vitest 295/295 + 17/17, all lints green, live-app census
clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016X9eh1s5sTx1o9Em9KBuwR
2026-08-14 09:25:32 +02:00
Viktor Vaczi
e14faeca8b jspi: retire the asyncify pipeline — knob, post-link tail, binaryen hooks
Phase 8 in the parent repo. Deleted: asyncify-scheduler.js, apply-asyncify.sh,
apply-finalize.sh, inject-dyncall-shims.sh, asyncify-imports/removelist.txt,
the wasm-opt/finalize stub pair, scripts/binaryen-hoist-pass/ (the fork stays
a dormant submodule; removal is a follow-up), bench/wasm-opt-bench.sh (README
marked historical), wasm/shims/context_sleep.cpp, and the sched-context
harness app + Makefile targets.

PCBJAM_ASYNC_BACKEND is gone: build-wx-wasm.sh hardcodes the jspi stamp
(still force-cleans pre-migration trees), build-kicad-target.sh gives editors
the JSPI link surface and the CLIs nothing (they pin ASYNCIFY=0), the stub
dance is replaced by an unconditional .real-restore, build-wasm-test.sh lost
its whole post-link loop, docker/build.sh's postprocess is the ENV shim only,
and Makefile.wasm links every app JSPI with the scheduler shim as a tracked
prerequisite. pcbjam_async_policy.h keys on __EMSCRIPTEN__.

jspi-scheduler.js: wxWasmMainLoopPump dropped from the wrap census (the
export died with the D5 detach); inert [TRACE] instrumentation removed.

CI: wasm-build.yml rewritten for the single-cache pipeline (one output cache
keyed on compile inputs; post-processed bytes cached after the shim);
opt_level input removed from both callers. wasm-cache-hash.mjs inputs now
cover patch-env-shim.mjs + jspi-scheduler.js + jspi-exports.txt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NDeBaKKhQztd8KiVtHuyXr
2026-08-13 08:39:12 +02:00
Gergő Törcsvári
d6c4efcf1f
Phase E complete: K4-K6 become token waits — the bridge set is converted, suite at baseline
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L2SU74acXyviwSxBhMunFe
2026-08-10 10:14:19 +02:00
Viktor Vaczi
703cb010b7 eeschema simulator: lazy ngspice_service worker — static sharedspice (XSPICE registry + CIDER), init_dll ifdef, e2e both engines
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 15:59:21 +02:00
Istvan Matejcsok
27992f4f18 feat(3d): gl1 shim M4+M6+M7 — GLU quadrics, production link, stub retired; 47/47 parity
- gl1_glu: gluCylinder/gluDisk/gluSphere per the SGI GLU reference
  tessellation (sin/cos phase, strip emission order, pole fans — Apple's
  GLU derives from the same source, so vertices match the goldens);
  emission goes through the public glBegin/glVertex entry points so
  quadrics record into display lists
- glLineWidth>1 one-time warning (browsers clamp to 1; affected coverage
  stays under the parity floor — zero floors.json overrides needed)
- production link site: build-kicad-target.sh now compiles wasm/gl1 from
  sources.txt and applies wrapped_symbols.txt --wrap flags (same manifests
  as the test harness); kicad_editor's RENDER_3D_OPENGL links against the
  real emulation layer instead of no-ops
- wasm/stubs/gl_ffp_stub.c deleted (role fully superseded; history in git)
- docs: 3d-regression README port-status section (floor-blind small
  geometry + line-width caveats), harness comments de-red-stated

Parity: 47/47 under the 0.02 floor, zero overrides. Native golden path
byte-identical to bb0e238 (whose gate ran green) — scenarios/, native/,
baseline/, manifest, floors, spec all untouched by the port.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 15:45:58 +02:00
Viktor Vaczi
db9d6ee04b feat(wasm): occ-split — lazy occ_service worker; kicad_editor drops OCC (−31%)
Move OpenCASCADE out of the merged editor image into occ_service: a separate
emscripten module (-sASYNCIFY=0, MODULARIZE, in-container -Oz finalize, 2N+8
pre-warmed pthread pool) booted lazily in a dedicated Web Worker on the first
STEP export or STEP/IGES model parse. kicad_editor.wasm ~190 MB -> 130 MB;
sessions that never touch OCC never fetch its 57 MB. STEP export works in the
browser for the first time: the unchanged desktop dialog runs EXPORTER_STEP,
whose wasm shadow suspends into globalThis.occService and the export bytes go
straight to a browser download (never entering the editor heap). STEP/IGES 3D
models parse in the worker via the oce shadow (S3D WriteCache/ReadCache wire).

- wasm/occ-service/: service CMake target (hooked from the kicad fork's
  top-level CMakeLists, wasm/editor pattern), embind entry
  (occExport/occLoadModel), wxConfig pre-js.
- wasm/stubs/{exporter_step,oce_plugin}_stub.cpp: EM_ASYNC_JS worker bridges
  (callee-shadowing; no caller #ifdefs).
- web/standalone: provider installed whenever the kicad_editor bundle boots
  (cross-face safe); ONE shared worker-boot source occ-worker.js (vite ?raw;
  the e2e stub reads the same file) — blob worker with locateFile absolutized
  against the glue URL; export download-name guard.
- deps: OCC builds with RapidJSON so its glTF/GLB writer exists — pinned to
  the vcpkg master snapshot 2025-02-26 (24b5e7a8b27f), the same code official
  KiCad consumes via vcpkg.json's opencascade[rapidjson]; rapidjson's latest
  tag (v1.1.0, 2016) is ill-formed under modern clang.
- tests: occ-export dialog e2e (lazy-fetch boundary + STEP download bytes),
  occ-probe incl. a 9-format matrix (step/stpz/brep/xao/ply/stl/glb/u3d/pdf),
  3d-viewer-models hard-asserts the worker parse; occ provider stub installed
  ambiently by the kicad fixtures.

Validated against desktop kicad-cli 10.0.4: geometric exact equality (bbox
delta 0 um, volume delta 0.0000%) for STEP/GLB/STL/BREP/STPZ across three
boards and option sweeps — with desktop OCC 7.9 vs wasm OCC 7.8; PLY/XAO/PDF
structurally equal; U3D same-size (quantizer float LSBs differ). Full kicad
e2e green on Firefox and Chromium; standalone verified end to end (lazy fetch
only on the Export click; export.step 60,628 B ISO-10303-21; loadModel 700 KB
STEP -> 569 KB scenegraph cache).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 12:39:58 +02:00
Gergő Törcsvári
d6ce380458
fix(wasm): add MODEL_SUBSTITUTION no-op stub for 3D-disabled pcbnew/footprint build
Provides wasm/stubs/model_substitution_stub.cpp — no-op IsWrlExtension /
STEP_CATALOG::Build / FindMatchFor — so pcbnew and footprint_editor link when the
3D viewer is off (KICAD_BUILD_3D_VIEWER_WASM=OFF). The KiCad 10 rebase made
dialog_migrate_3d_models.cpp reference these, which live in the unlinked 3D
library. The browser build has no 3D viewer, so model migration finds no
substitutions. Bumps kicad to the matching CMake wiring (fef0343).

Verified: pcbnew + footprint_editor compile and link clean (eeschema/symbol_editor
unaffected).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:14:47 +02:00
Istvan Matejcsok
cdaa96250d fix(wasm): KiCad 10 kiplatform/libgit2 stubs, e2e fixtures, asyncify -g hook
- wasm/kiplatform: add EnableDarkMode, IO::TimestampDir, UI::AllowNetworkFileSystems,
  UI::CancelPendingScroll, SECRETS::DeleteSecret (new KiCad 10 functions).
- wasm/stubs/libgit2_stub.c: ~156 no-op stubs for KiCad 10's restructured git
  backend + git-backed local history + text_eval VCS.
- tests/kicad: bump the demo project dir 9.99 -> 10.0 (KiCad 10 stores projects
  under /home/kicad/documents/kicad/10.0/) — fixes load-pcb + 3d-viewer e2e.
- scripts/common/apply-asyncify.sh: ASYNCIFY_EXTRA_OPTS hook (e.g. -g for
  symbolizable wasm traces).
- kicad submodule -> ef00c2d3 (KiCad 10 link + runtime adaptations).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:30:25 +02:00
Istvan Matejcsok
3e3e97aec7 wasm-port-rebase: KiCad 10.0.4 rebase + WASM build adaptations
Root-side changes for the wasm-port-rebase work:
- kicad submodule bumped to wasm-port-rebase (43-commit rebase onto KiCad 10.0.4
  + the KiCad-10 WASM source adaptations)
- wasm/kiplatform/policy.cpp: GetPolicyEnumUInt -> std::optional (KiCad 10 API)
- wasm/stubs/api_plugin_stub.cpp: API_PLUGIN_MANAGER signature sync (KiCad 10 API)

Compiles 100% for pcbnew (3D viewer on, -O1); WASM link + e2e parity still pending.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 10:30:25 +02:00
Istvan Matejcsok
0195ff0941 feat: ✨ enable WASM 3D viewer build — FFP link stubs, drop glemu shim
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 09:21:37 +02:00
Istvan Matejcsok
c148443b7b refactor: 💡 remove orphaned files 2026-06-05 13:18:24 +02:00
Balint Ipkovich
4467bcd2c4 feat: gerbview WASM port 2026-06-03 14:23:57 +02:00
Balint Ipkovich
d735779e23 feat: pl_editor WASM port + browser file dialog fixes
Brings up KiCad's pagelayout_editor (drawing-sheet editor) in the
browser, to roughly the same "boots, canvas visible, partially usable
in-session" level as the existing pcbnew/eeschema/calculator ports.

Build:
- docker/build.sh: add pl_editor to the unified app dispatch (case,
  subdir map, all-loop).
- scripts/kicad/build-kicad-target.sh: add pl_editor to the case;
  upstream target name pl_editor under source subdir pagelayout_editor.
- scripts/kicad/build-pl_editor.sh: 7-line thin wrapper matching the
  pcbnew/eeschema/calculator pattern.
- tests/scripts/setup-kicad-wasm.sh: copy_app pl_editor.

App glue:
- wasm/stubs/nl_pl_editor_plugin_stub.cpp: no-op SpaceMouse plugin so
  pl_editor_frame.cpp's NL_PL_EDITOR_PLUGIN symbols resolve. Mirrors
  nl_pcbnew_plugin_stub.cpp.
- tests/apps/kicad/pl_editor.html: browser shell. preRun creates
  /home/kicad and FS.chdir there so file dialogs land somewhere
  friendly instead of MEMFS root (/dev/, /proc/, etc.).

E2E coverage:
- tests/kicad/pl_editor.spec.ts: 5 tests — smoke (canvas, no abort),
  wizard, File menu has Open/Save As, file-dialog folder-navigation
  regression, canvas + toolbar metrics.
- tests/e2e/filedialog-folder-nav.spec.ts: wxWidgets-level twin of
  the regression test (exercises the underlying widget directly via
  the standalone filedialog_test app).

Submodule bumps:
- kicad → feature/pl-editor (WASM gating in pagelayout_editor's
  CMakeLists + navlib stub).
- wxwidgets → feature/pl-editor (wxGenericFileDialog::OnOk navigates
  into selected directories; wasm/mouse.cpp emits wxEVT_LEFT_DCLICK
  via timestamp-based double-click detection — the latter benefits
  every wxWidgets-WASM app).

See features/pl-editor/ for the design doc + per-repo diff patches.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 10:30:56 +02:00
Gergő Törcsvári
730147d690
feat(schematic): eeschema WASM build + e2e harness 2026-05-29 16:01:17 +02:00
Viktor Vaczi
71d2444729 feat(wasm): Disable 3D viewer with comprehensive stubs
- Set KICAD_BUILD_3D_VIEWER_WASM=OFF in build script
- Add comprehensive 3D canvas stubs (~500 lines) including:
  - EDA_3D_CANVAS with wxWidgets event table
  - BOARD_ADAPTER, EDA_3D_VIEWER_SETTINGS
  - PANEL_PREVIEW_3D_MODEL with all event handlers
  - DIALOG_SELECT_3DMODEL
  - TRACK_BALL camera
  - BBOX_2D, BBOX_3D, BVH_CONTAINER_2D
  - OGL_ATT_LIST::GetAttributesList
- Add 3D scenegraph stubs for VRML export
- Update KiCad submodule with WASM guards
- Update WebGL GAL implementation plan to COMPLETE status

All 4 phases of the WebGL GAL implementation are now complete:
- Phase 1: Native test harness (28 scenarios)
- Phase 2: WebGL GAL implementation (~27,800 lines)
- Phase 3: Complete API coverage
- Phase 4: KiCad integration with 3D viewer stubs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 15:15:50 +01:00
Viktor Vaczi
582b282a6c Add missing GLU_TESS_BOUNDARY_ONLY constant for idftools
The idftools/vrml_layer.cpp uses this GLU tessellation constant
which was missing from our WASM GLU stub header.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 11:24:24 +01:00
Viktor Vaczi
cb58b43bd1 Enable OpenGL GAL and 3D viewer stubs for WASM
Changes:
- Add glu_wasm_impl.cpp: GLU tesselator using KiCad's earcut triangulation
- Add GL/glu.h: GLU header for WASM builds
- Add 3D viewer stubs for KICAD_BUILD_3D_VIEWER_WASM=ON
- Remove obsolete gl_canvas_stub.cpp (OpenGL now uses real impl)
- Remove obsolete glu_stub.c (replaced by glu_wasm_impl.cpp)
- Update build-pcbnew.sh comment about GLU implementation

The OpenGL GAL now works in WASM using WebGL with LEGACY_GL_EMULATION.
3D viewer is stubbed out but builds successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 08:19:40 +01:00
Viktor Vaczi
9c271996c2 Fix KiCad WASM build and runtime errors
Build improvements:
- Change -O0 to -O1 to fix "local count too large" asyncify error
- Add wasm-emscripten-finalize to host (Docker OOMs on large WASM)
- Use -gseparate-dwarf for smaller main binary with debug info
- Build native protoc for code generation
- Add more functions to asyncify removelist

Runtime fixes:
- Add inject-dyncall-shims.sh to fix "dynCall_* is not defined" in Emscripten 4.x
- Update wxwidgets with browserInfo.name fix

New stubs and bindings:
- Add Embind bindings for JavaScript interop
- Add stubs for scripting, API plugin, PCB frame, navlib

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 16:30:53 +01:00
Viktor Vaczi
898e079ef2 Enable 3D viewer in KiCad WASM build
Build the 3D viewer code for WASM instead of stubbing it out.
This is simpler to maintain than complex header stubs.

Changes:
- Enable KICAD_BUILD_3D_VIEWER_WASM=ON in build script
- Remove -gsource-map to avoid OOM in wasm-emscripten-finalize
- Add OpenGL stubs for fixed-function pipeline (WebGL ES 2.0 only)
- Add GLU stub for gluErrorString
- Add NNG stub for IPC API (sockets don't work in WASM)
- Add PCBnew scripting stub
- Expand curl and libgit2 stubs

The 3D viewer code compiles but won't render at runtime since
OpenGL GAL is disabled and Cairo GAL is used instead.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-21 14:21:29 +01:00
Viktor Vaczi
6771e7de74 Fix Asyncify and improve build process
Build system improvements:
- Add wasm-opt stub for Docker build to bypass asyncify in container
- Add apply-asyncify.sh script for host-side asyncify transformation
- Update build-pcbnew.sh to install wasm-opt stub and add EXPORTED_RUNTIME_METHODS
- Add --with-zlib=sys to wxWidgets configure for proper zlib linking
- Improve update-baseline-screenshots.sh to only copy new/significantly changed files

wxWidgets submodule update:
- Fix EM_JS to EM_ASYNC_JS for proper Asyncify registration

Test updates:
- Add new baseline screenshots for bitmapbuttons, dnd, gridrenderers, printpreview, specialized tests
- Add kicad-pcbnew initial screenshot
- Fix wxgrid-controls.png and wxgrid-dedicated-page.png (were showing errors)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 11:59:50 +01:00
Viktor Vaczi
9f4ed1e51e Add KiCad PCBnew WASM build support and documentation
Build infrastructure:
- Update build-pcbnew.sh with stub library compilation
- Update build-wxuniversal-wasm.sh with library symlinks and stubs
- Add stub libraries for libgit2 and curl (network ops via JS)
- Add WASM-specific CMake Find modules

Documentation:
- Add KICAD_WASM_BUILD.md with complete modification list
- Document 68 KiCad files modified for WASM support
- Document disabled features and reasons
- Document stub libraries and wxWidgets changes

Submodule updates:
- kicad: Add WASM/Emscripten build support (wasm-port branch)
- wxwidgets: Add KiCad compatibility fixes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-08 18:26:57 +01:00