- Dispatch/init.luau: InitDispatch(module) 팩토리(§6) — 인스턴스별 레지스트리 +chains(Relate), getHandler(순수 스캔)/process(하강 diff (A)/(B), 점유 마커, SetStrong 선행, retractor 생략 즉시 error)/3-인자 retractFrom(꼬리 역순, 구멍 error level 1)/addHandler(등록 시 정렬, 동률 경고는 module.debug)/ listHandlers(순수 조회)/drive((b) 본체 루프만 — ⓪⓪' 단위 2, (a)(c) M8). 매치 실패는 typeof+브랜드(is* 프로브)+provider 안내, 지연 생성 - spec.dispatch.luau(12절: (A)/(B)·깊은 체인 힌트·같은 핸들러 두 슬롯·조건부 재위임·다른 키 위임·동률·격리) / spec.drive.luau(F-4-1 언어 동작 실측) — 전부 PASS, luau-analyze·selene 클린 - H-212(①): base 의사코드 error 셋이 error 계약(영어+level, 08-25) 이전 표기 — dispatch-core-plan.md와 코드 같은 커밋 정정 - H-213(①): HANDLER_PRIORITY_* 리터럴 값은 문서 미정 — 1000/0/-1000/-1000000 - H-214(②): listHandlers·동률 경고가 원하는 핸들러 "이름"이 계약 3종에 없음 — round12 §4 문항 등재, 코드는 TODO(H-214) 마커 1곳 - 스파이크 01 폐기(직전 커밋에서 done/ 이동): spec.drive가 같은 질문을 상시 회귀로 대체(§6 승인) — STATUS.md·ROADMAP 재검증 대기 절 [x] - ROADMAP M3 체크박스: 단위 1 몫 여섯 [x](drive 범위 절단 주석 포함) Co-authored-by: qwreey <me@qwreey.moe> Claude-Session: https://claude.ai/code/session_01LF78pXeFGD1ZSVD3ifteYG
66 lines
2.2 KiB
Text
66 lines
2.2 KiB
Text
--[[
|
|
Dispatch.drive — M3 unit-1 scope: pipeline stage (b) only, the single
|
|
generalized `for` (`.claude/base/bind-system-plan.md` "`New(name)(props)`
|
|
파이프라인 의사코드"; scope cut: round12 brief §6).
|
|
|
|
This spec measures the *language behavior* the contract leans on (`F-4-1`):
|
|
a generalized `for` over a plain Luau table gives the whole array part
|
|
before the hash part, and the array part in index order. That is the exact
|
|
question the retired spike `01` (luau-test/rewrite-required) was due to
|
|
ask — this spec replaces it as a standing regression (round12 brief §6).
|
|
]]
|
|
|
|
local Quad = require("../src")
|
|
local QuadTypes = require("../roblox_packages/quad_types")
|
|
|
|
local q = Quad.New()
|
|
local log: { string } = {}
|
|
q.Dispatch.addHandler({
|
|
isHandlable = function(_inst: any, _k: any, _v: any): boolean
|
|
return true
|
|
end,
|
|
priority = q.Dispatch.HANDLER_PRIORITY_NORMAL,
|
|
process = function(_inst: any, k: any, v: any, index: number): (any?) -> ()
|
|
table.insert(log, `{tostring(k)}={tostring(v)}@{index}`)
|
|
return Quad.Void
|
|
end,
|
|
} :: QuadTypes.Handler)
|
|
|
|
print("=== 1. 배열 파트 전체가 해시 파트보다 먼저 + 배열 안에서는 index 순서 ===")
|
|
do
|
|
table.clear(log)
|
|
local flattened: { [any]: any } =
|
|
{ "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "a10", Size = "s", Text = "t", Name = "n" }
|
|
q.Dispatch.drive({}, flattened)
|
|
assert(#log == 13, `13 entries processed, got {#log}`)
|
|
for i = 1, 10 do
|
|
assert(log[i] == `{i}=a{i}@1`, `array slot {i} in index order before any hash key, got "{log[i]}"`)
|
|
end
|
|
local hashSeen: { [string]: boolean } = {}
|
|
for i = 11, 13 do
|
|
hashSeen[log[i]] = true
|
|
end
|
|
assert(hashSeen["Size=s@1"] and hashSeen["Text=t@1"] and hashSeen["Name=n@1"], "all hash keys after the array part")
|
|
print("PASS")
|
|
end
|
|
|
|
print()
|
|
print("=== 2. 모든 진입은 체인 인덱스 1 ===")
|
|
do
|
|
for _, entry in log do
|
|
assert(string.sub(entry, -2) == "@1", `drive enters every chain at index 1, got "{entry}"`)
|
|
end
|
|
print("PASS")
|
|
end
|
|
|
|
print()
|
|
print("=== 3. 빈 props — no-op (아무 핸들러도 안 불림) ===")
|
|
do
|
|
table.clear(log)
|
|
q.Dispatch.drive({}, {})
|
|
assert(#log == 0, "empty flattened processes nothing")
|
|
print("PASS")
|
|
end
|
|
|
|
print()
|
|
print("=== ALL PASS ===")
|