diff options
Diffstat (limited to 'docs/research/016-pointer-routing.md')
| -rw-r--r-- | docs/research/016-pointer-routing.md | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/docs/research/016-pointer-routing.md b/docs/research/016-pointer-routing.md new file mode 100644 index 0000000..933e505 --- /dev/null +++ b/docs/research/016-pointer-routing.md @@ -0,0 +1,98 @@ +# 016 — 대상마다 복제하던 포인터 연결 제거 + +2026-09-23. 앞 단계는 규칙 본문을 공유했지만, 세 도형의 드래그를 위해 입력 세 개와 +반응 연결 열두 개를 따로 만들었다. 이번에는 **입력 하나와 반응 네 개에 대상 표를 연결**한다. +현재 잡은 도형의 상태 구간을 규칙에 전달하고, 접촉 소유권은 도형별로 유지한다. + +## 작성과 사용 + +```text +input drag = pointer { + green_box: green + blue_box: blue + amber_box: amber +} +on drag.down use grab(drag.target) +on drag.move use move(drag.target) +on drag.up use drop(drag.target) +on drag.cancel use cancel(drag.target) +``` + +작업 화면을 새로고침하고 **입력 묶어서 배치 → 예제 불러오기 → 코드 적용**을 누른다. +[전체 작성물](../../prototypes/workbench/examples/routed-layout.pure)은 이전과 같은 +잡은 위치 유지, 경계 제한, 놓기 확정, 취소 복귀, 선택한 도형의 방향키 조정을 제공한다. +한 그룹 안의 도형 두 개를 동시에 움직일 수 있다. 하나를 놓거나 취소해도 다른 도형의 +소유권은 유지되며, 이미 놓은 도형은 다른 접촉을 취소해도 되돌아가지 않는다. + +같은 record 타입의 item끼리 묶는다. 도형과 대상의 연결은 명시하지만 네 반응은 +대상마다 작성하거나 컴파일해 복제하지 않는다. 마지막 입력 표시에는 대상 도형도 나온다. +CLI는 `point-target drag green_box move 210 220`으로 같은 경로를 실행한다. + +## 실제 실행 표현 + +컴파일러는 도형 이름을 item의 연속 필드 구간에 연결한다. VM에 저장되는 대상 하나는 +`input, base, count` 세 바이트다. 그룹 반응의 메타데이터에는 ‘이번 사건의 대상’을 +사용한다는 표시와 필드 수만 둔다. 명령 본문과 연결 수는 도형 수만큼 늘어나지 않는다. + +브라우저는 처음 잡은 도형을 캡처 기록에 유지한다. 런타임은 코드 적용 시 만든 이름 +조회 표로 대상 번호를 찾고, VM은 그 번호로 활성 대상 표를 직접 읽는다. +포인터가 움직일 때마다 그룹의 모든 도형을 검색하거나 각 도형의 규칙을 실행하지 않는다. +기존의 제한된 핸들러 목록에서 사건 번호를 비교하는 순회는 남아 있다. + +소유권 키는 입력 이름과 도형 이름의 조합이다. 같은 도형의 두 번째 접촉은 소유권을 +가져갈 수 없다. `releaseAll`은 잡고 있는 도형 각각에 취소를 한 번씩 보낸다. +그룹끼리 같은 item을 중복 연결하는 것도 거절해 필드 구간이 겹치는 캡처를 막는다. +작성자가 다른 전역 상태나 명시적 대상에 쓰는 일반 반응까지 금지하는 정책은 아니다. + +VM은 잘못된 대상 번호, 다른 입력의 대상, 누락된 대상, 범위를 벗어난 필드를 거절한다. +하나의 사건에서 앞의 반응이 쓴 값도 뒤의 반응이 실패하면 함께 취소한다. +준비 중인 연결 표는 활성 표를 바꾸지 않는다. 소스 적용과 파일 복원은 입력을 모두 +놓은 뒤에만 가능하고, 이름을 기준으로 표를 다시 만든다. 파일에는 물리 대상 번호를 저장하지 않는다. + +## 확인한 비용과 한계 + +동일한 최종 코어에 두 작성물을 넣은 저장 구조 회계다. 속도 벤치마크는 하지 않았다. + +| 항목 | 공유 규칙 + 대상별 입력 | 공유 규칙 + 그룹 입력 | +|---|---:|---:| +| 전체 입력 | 7 | 5 | +| 포인터 반응 연결 | 12 | 4 | +| 전체 반응 연결 | 24 | 16 | +| 저장 명령 | 117 | 117 | +| 대상 표 | 0 B | 9 B | +| 사용 중인 명령·연결·대상 표 | 2,256 B | 2,137 B | +| 숫자 상태 | 25 | 25 | + +대상 표 24칸을 예약하면서 활성/준비 프로그램에 각각 80 B가 추가됐다. +코어 고정 예약은 **19,904 → 20,064 B**, Wasm 선형 메모리는 64 KiB로 유지된다. +현재 예제의 사용 자료는 줄었지만, 고정 예약은 늘었다. JS의 조회 Map과 메타데이터, +브라우저 전체 메모리는 이 수치에 포함하지 않는다. 전체 메모리나 실행 속도의 우위로 해석하지 않는다. +[구조 회계](../../prototypes/workbench/results/2026-09-23-pointer-routing/representation.json). + +1·3·9·24개의 작은 대상을 컴파일해 하나의 입력과 하나의 이동 반응이 유지되는지도 검사했다. +이는 기존 입력 8개 한도와 대상 수를 분리했는지 확인하는 경계 검사다. +큰 앱이나 많은 도형의 성능 실험으로 세지 않는다. 총 상태 32개, 출력 24개 등의 +기존 한도는 그대로이며, 현재 Tile의 8필드 구성으로 24개 도형을 만들 수 있다는 뜻도 아니다. + +## 검증과 남은 작업 + +코어 검사 35개와 Node/CLI 검사 83개가 통과했다. 기존 배치와 동일한 입력을 전달해 +모든 필드와 출력을 비교했고, 동시 접촉·일부 취소·소유권 침범 거절·그룹 혼동 거절· +실패 원자성·표시 캐시 갱신·선언 순서 변경·제거 후 재선언·파일 복원을 확인했다. + +그룹 예제의 브라우저 확인 30개, 기존 작성 흐름 44개, 이전 대상별 포인터 흐름 +23개도 통과했다. +브라우저에서는 실제 마우스와 Chromium CDP 터치로 조작한다. 개별 접촉 종료 검사에서 +처음에 남겨둘 접촉을 종료하도록 보낸 오류를 바로잡았다. 기록된 실제 `pointerup`과 +남은 소유권을 함께 확인했다. 이동 검사는 CDP 명령 응답 이후 실제 사건이 +반영될 때까지 기다린다. 이 재현은 실제 모바일 하드웨어 검증을 대신하지 않는다. +[검증 자료와 재현](../../prototypes/workbench/results/2026-09-23-pointer-routing/README.md). + +이 결과는 입력마다 대상을 별도 연결하던 비용을 분리한 구현이다. 독창적인 새 +프로그래밍 개념이나 대규모 서비스 최적화의 증거로 제시하지 않는다. + +다음 문제는 **선택 대상의 식별과 키 입력의 직접 전달**이다. 현재 예제의 `selected`와 +`id`는 작성한 숫자 상태이며, 방향키는 여전히 대상별 조건을 검사한다. 이를 해결할 때는 +선택 없음, 선택 대상 제거, 저장 복원 뒤 선택, 잡고 있는 대상과 선택이 다를 때의 정책을 +먼저 고정해야 한다. 동적 생성·삭제에는 오래된 입력이 재사용된 슬롯으로 전달되지 않는 +수명 식별도 필요하다. 이번 대상 번호는 정적 정의 안의 주소이며 그 역할을 대신하지 않는다. |
