Skip to content

feat: geulbus-core 엔진 이행 1단계 (단일 테이블 자판) - #106

Open
lens0021 wants to merge 10 commits into
mainfrom
feat/geulbus-engine
Open

feat: geulbus-core 엔진 이행 1단계 (단일 테이블 자판)#106
lens0021 wants to merge 10 commits into
mainfrom
feat/geulbus-engine

Conversation

@lens0021

Copy link
Copy Markdown
Collaborator

개요

한글 조합 엔진을 geulbus-core로 통일하는 1단계. 설계와 단계 계획은 docs/geulbus-migration.md 참고 (chaotic-ground/geulbus#2, chaotic-ground/geulbus#3 후속).

변경

Rust 래퍼 (rust/teogeul-engine)

  • LayoutData 테이블(첫가끝/호환 자모/리터럴)을 날개셋 Layout 으로 변환하는 빌더
  • UniFFI 인터페이스: GeulbusEngine.newPlain(name, rows, combos), press(key, shift), backspace(), flush(), reset()
  • 호환 자모 자음 감지 시 두벌식 배치(받침 이중 역할 + 도깨비불) 자동 활성화
  • geulbus-core 는 두벌식/D·E·F 확장 브랜치(geulbus#3)를 rev 핀으로 참조, 0.3 출시 후 크레이트 참조로 전환

빌드

  • rust-android-gradle 로 4개 ABI cargo 빌드 → jniLibs
  • 호스트 빌드 + uniffi-bindgen 으로 Kotlin 바인딩 생성 (preBuild)
  • Robolectric 테스트용 jna.library.path 설정, CI 에 Rust 타겟 설치 추가

Kotlin

  • EngineMode.useGeulbus: 세벌식 390/391/단모음/순2014, 두벌식 표준/NK 6개 모드가 새 엔진 사용
  • KeyEventHandler 에 geulbus 분기 (KeyOutcome → InputConnection)
  • jamoSet(신세벌식·3-2015 계열)·안마태·네벌식은 기존 HangulEngine 유지 (2단계에서 이행)

테스트

  • Rust 단위 테스트 15개 (두벌식 도깨비불·겹받침 분리·된소리·백스페이스, 세벌식 390 조합) — 로컬 통과
  • Robolectric 종단 테스트 6개 (LayoutData → FFI → 조합 → InputConnection)

알려진 의도적 변화 (major 예정)

  • 모아치기 시간 설정 제거는 3단계(전체 이행 후)로 예정
  • 미완성 낱자의 preedit 표기가 일부 달라질 수 있음 (첫가끝/호환 자모 렌더링)

🤖 Generated with Claude Code

lens0021 and others added 3 commits July 12, 2026 17:51
한글 조합 로직을 geulbus-core 로 통일하는 1단계
(chaotic-ground/geulbus#2, docs/geulbus-migration.md 참고).

- rust/teogeul-engine: LayoutData 테이블을 날개셋 Layout 으로 변환하는
  빌더와 UniFFI 인터페이스(GeulbusEngine: press/backspace/flush/reset)
- 두벌식(도깨비불·겹받침 분리 포함)과 세벌식 390 시나리오 테스트 15개
- 상태 의존 자판(신세벌식·3-2015 계열)은 geulbus-core 의 가상 낱자
  확장을 기다려 후속 이행 (설계 문서 참고)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- rust-android-gradle 로 Android 4개 ABI cargo 빌드 → jniLibs
- 호스트 cargo 빌드 + uniffi-bindgen 으로 Kotlin 바인딩 생성
  (build/generated/uniffi/kotlin, preBuild 에 연결)
- JNA 의존성(Android aar, JVM 테스트 jar)과 Robolectric 용
  jna.library.path 설정
- CI 에 Rust Android 타겟 설치 단계 추가

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
세벌식 390/391/단모음/순2014와 두벌식 표준/NK 가 geulbus-core(Rust)로
조합한다. KeyEventHandler 는 press/backspace 의 KeyOutcome 을
InputConnection 에 반영하고, jamoSet·안마태·네벌식 모드는 기존
HangulEngine 경로를 유지한다 (이행 단계는 docs/geulbus-migration.md).

- EngineMode.useGeulbus 로 모드별 엔진 선택
- GeulbusHangul: LayoutData 테이블 → FFI 레코드 변환
- 두벌식 도깨비불/된소리/백스페이스와 세벌식 390 조합의
  Robolectric 종단 테스트 추가

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lens0021 and others added 6 commits July 12, 2026 18:03
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rust-android-gradle 이 구성 시점에 NDK 를 요구한다. ndkVersion 을
지정하면 AGP 가 없는 NDK 를 자동 설치한다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AGP 의 NDK 자동 설치는 실행 시점에만 일어나는데 rust-android-gradle 은
구성 시점에 NDK 디렉터리를 조회하므로, sdkmanager 로 미리 설치한다.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- rust/src/bin/uniffi-bindgen.rs 가 루트 .gitignore 의 bin/ 규칙에
  걸려 커밋에서 빠져 있었다. rust/.gitignore 에 예외 추가.
- IMEService import 순서 (ktlint)
- rust-android-gradle cargo 태스크를 구성 캐시 비호환으로 표시

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- EngineError 의 message 필드가 생성된 Kotlin 예외의 Throwable.message
  와 충돌하므로 reason 으로 변경
- rust-android-gradle 이 rustJniLibs 를 스스로 jniLibs 에 등록하므로
  수동 srcDir 등록 제거 (Duplicate resources)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
chaotic-ground/geulbus#3 리뷰에서 두벌식 받침을 이력에 초성이 아닌
종성 갈래로 기록하도록 고쳐졌다(기존 C0 특수글쇠·백스페이스 모드와의
충돌 방지). teogeul 은 press/backspace 만 쓰므로 관측 가능한 동작
차이는 없다 — rust 테스트 15개 무회귀 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2/3단계와 geulbus-core 0.3 출시를 이슈로 남겼다
(teogeul#107, teogeul#108, geulbus#12).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant