Skip to content

Commit c4900a3

Browse files
cuzicclaude
andcommitted
refactor: 重複パターン4種を共通ヘルパーに集約
- observer::gji_idle_ms(): 2行の idle 計算を関数化(6箇所削減) - WindowsPlatform::dispatch_gji_event(): gji_on_event+dispatch_gji_response 4行→1行(5メソッド簡略化) - Output::on_f22_f21_sent(): borrow_mut+f22+f21 の3行を1行に(probe_io 2箇所) - KeyInjector::format_vk_run(): VK map+join を関数化(send_vk_runs* 3メソッド共用) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent b0cd4e9 commit c4900a3

5 files changed

Lines changed: 42 additions & 66 deletions

File tree

crates/awase-windows/src/output/key_injector.rs

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -227,23 +227,22 @@ impl KeyInjector {
227227
}
228228
}
229229

230+
fn format_vk_run(run: &[(VkCode, bool)]) -> String {
231+
run.iter()
232+
.map(|&(v, s)| if s { format!("S{v:02X}") } else { format!("{v:02X}") })
233+
.join(",")
234+
}
235+
230236
/// VK run 分割送信: 同一 VK 連続境界でバッチを分割して IME のオートリピート誤検出を回避する。
231237
pub(crate) fn send_vk_runs(chars: &[(VkCode, bool)], cold_seq: u32) {
232238
let runs = Self::split_vk_runs(chars);
233239
let total_runs = runs.len();
234240

235241
for (run_idx, run) in runs.into_iter().enumerate() {
236-
let last_io = crate::tsf::observer::gji_last_io_ms();
237-
let run_gji_idle = crate::hook::current_tick_ms().saturating_sub(last_io);
242+
let run_gji_idle = crate::tsf::observer::gji_idle_ms();
238243
log::debug!(
239244
"[h1-run] cold={cold_seq} run={run_idx}/{total_runs} gji={run_gji_idle}ms vks=[{}]",
240-
run.iter()
241-
.map(|&(v, s)| if s {
242-
format!("S{v:02X}")
243-
} else {
244-
format!("{v:02X}")
245-
})
246-
.join(","),
245+
Self::format_vk_run(&run),
247246
);
248247
Self::send_vk_run_batch(run, VkMarker::Tsf);
249248
}
@@ -257,17 +256,10 @@ impl KeyInjector {
257256
let runs = Self::split_vk_runs(&f2_plus_chars);
258257
let total_runs = runs.len();
259258
for (run_idx, run) in runs.into_iter().enumerate() {
260-
let last_io = crate::tsf::observer::gji_last_io_ms();
261-
let run_gji_idle = crate::hook::current_tick_ms().saturating_sub(last_io);
259+
let run_gji_idle = crate::tsf::observer::gji_idle_ms();
262260
log::debug!(
263261
"[h1-run] cold={cold_seq} run={run_idx}/{total_runs} gji={run_gji_idle}ms vks=[{}] (f2-leading)",
264-
run.iter()
265-
.map(|&(v, s)| if s {
266-
format!("S{v:02X}")
267-
} else {
268-
format!("{v:02X}")
269-
})
270-
.join(","),
262+
Self::format_vk_run(&run),
271263
);
272264
Self::send_vk_run_batch(run, VkMarker::Tsf);
273265
}
@@ -297,17 +289,10 @@ impl KeyInjector {
297289
let total_runs = runs.len();
298290

299291
for (run_idx, run) in runs.into_iter().enumerate() {
300-
let last_io = crate::tsf::observer::gji_last_io_ms();
301-
let run_gji_idle = crate::hook::current_tick_ms().saturating_sub(last_io);
292+
let run_gji_idle = crate::tsf::observer::gji_idle_ms();
302293
log::debug!(
303294
"[h1-run] cold={cold_seq} run={run_idx}/{total_runs} gji={run_gji_idle}ms vks=[{}] ({leading_label})",
304-
run.iter()
305-
.map(|&(v, s)| if s {
306-
format!("S{v:02X}")
307-
} else {
308-
format!("{v:02X}")
309-
})
310-
.join(","),
295+
Self::format_vk_run(&run),
311296
);
312297
Self::send_vk_run_batch(run, VkMarker::Tsf);
313298
}

crates/awase-windows/src/output/mod.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,10 +313,18 @@ impl Output {
313313
.set(self.ime_mode_focus_gen.get().wrapping_add(1));
314314
}
315315

316+
/// VK_IME_OFF → VK_IME_ON の連続送信を ImeModeFsm に通知する。
317+
///
318+
/// `send_sacrificial_ime_off_on` / `send_chrome_gji_reinit_and_poll` で使う。
319+
pub(crate) fn on_f22_f21_sent(&self) {
320+
let mut fsm = self.ime_mode_fsm.borrow_mut();
321+
fsm.on_f22_sent();
322+
fsm.on_f21_sent();
323+
}
324+
316325
/// VK_IME_ON/OFF 送信時に `ImeModeFsm` の belief を即時更新する。
317326
///
318-
/// `send_chrome_gji_reinit_and_poll` は個別に `on_f22_sent()`/`on_f21_sent()` を呼ぶため、
319-
/// このメソッドは通常 IME ON/OFF(`send_engine_state_ime_key` 経由)用。
327+
/// 通常 IME ON/OFF(`send_engine_state_ime_key` 経由)用。
320328
pub(crate) fn on_ime_mode_vk_sent(&self, vk: VkCode) {
321329
let mut fsm = self.ime_mode_fsm.borrow_mut();
322330
if vk == crate::vk::VK_IME_ON {

crates/awase-windows/src/output/probe_io.rs

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -228,12 +228,7 @@ impl ProbeIo for Output {
228228
make_key_input_ex(VK_IME_ON, true, IME_KANJI_MARKER),
229229
];
230230
log::debug!("[sacr-warmup] cold={cold_seq} VK_IME_OFF→ON 送信(vim 安全プローブ)");
231-
// ImeModeFsm belief を即時更新する。
232-
{
233-
let mut fsm = self.ime_mode_fsm.borrow_mut();
234-
fsm.on_f22_sent();
235-
fsm.on_f21_sent();
236-
}
231+
self.on_f22_f21_sent();
237232
unsafe {
238233
SendInput(
239234
&inputs,
@@ -335,11 +330,7 @@ impl ProbeIo for Output {
335330
let _ = crate::win32::send_input_safe(&inputs);
336331

337332
// 2. ImeModeFsm belief を即時更新: VK_IME_OFF → Off, VK_IME_ON → Hiragana。
338-
{
339-
let mut fsm = self.ime_mode_fsm.borrow_mut();
340-
fsm.on_f22_sent();
341-
fsm.on_f21_sent();
342-
}
333+
self.on_f22_f21_sent();
343334

344335
// 3. async IMC ポーリング開始(CHROME_GJI_REINIT_CONFIRM_MS の間、10ms ごとに発行)。
345336
// with_app 再入を避けるため spawn_local で defer する。
@@ -534,8 +525,7 @@ where
534525
// 診断ログ: IMC_GETCONVERSIONMODE は SendMessageTimeoutW を呼ぶため、
535526
// with_app 再入を避けるため async タスクへオフロードする (Step 3)。
536527
// ログ出力タイミングが数 ms 遅れるが診断用途のため許容。
537-
let last_io = crate::tsf::observer::gji_last_io_ms();
538-
let gji_idle = crate::hook::current_tick_ms().saturating_sub(last_io);
528+
let gji_idle = crate::tsf::observer::gji_idle_ms();
539529
let romaji_owned: String = romaji.clone();
540530
let chars_len = chars.len();
541531
win32_async::spawn_local(async move {

crates/awase-windows/src/platform.rs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,7 @@ impl WindowsPlatform {
463463
crate::tsf::composition_fsm::CompositionEvent::FocusChange { tsf_mode },
464464
None,
465465
);
466-
let last_io = crate::tsf::observer::gji_last_io_ms();
467-
let gji_idle_ms = crate::hook::current_tick_ms().saturating_sub(last_io);
466+
let gji_idle_ms = crate::tsf::observer::gji_idle_ms();
468467
let resp = self.output.gji_on_event(crate::tsf::gji_fsm::GjiEvent::FocusChange {
469468
injection_mode,
470469
gji_idle_ms,
@@ -495,20 +494,21 @@ impl WindowsPlatform {
495494

496495
/// IME ON を GjiFsm に通知する(`on_ime_applied(open=true)` から呼ぶ)。
497496
pub(crate) fn gji_on_ime_on(&mut self, injection_mode: crate::output::types::InjectionMode) {
498-
let last_io = crate::tsf::observer::gji_last_io_ms();
499-
let gji_idle_ms = crate::hook::current_tick_ms().saturating_sub(last_io);
497+
let gji_idle_ms = crate::tsf::observer::gji_idle_ms();
500498
let resp = self
501499
.output
502500
.gji_on_event(crate::tsf::gji_fsm::GjiEvent::ImeOn { injection_mode, gji_idle_ms });
503501
self.dispatch_gji_response(resp);
504502
}
505503

504+
fn dispatch_gji_event(&mut self, event: crate::tsf::gji_fsm::GjiEvent) {
505+
let resp = self.output.gji_on_event(event);
506+
self.dispatch_gji_response(resp);
507+
}
508+
506509
/// IME OFF を GjiFsm に通知する(`on_ime_applied(open=false)` から呼ぶ)。
507510
pub(crate) fn gji_on_ime_off(&mut self) {
508-
let resp = self
509-
.output
510-
.gji_on_event(crate::tsf::gji_fsm::GjiEvent::ImeOff);
511-
self.dispatch_gji_response(resp);
511+
self.dispatch_gji_event(crate::tsf::gji_fsm::GjiEvent::ImeOff);
512512
}
513513

514514
/// TIMER_GJI_LONG_IDLE ハンドラ。LongIdle タイムアウトを GjiFsm に通知する。
@@ -522,21 +522,15 @@ impl WindowsPlatform {
522522
/// `on_passthrough_key` の PassthroughKey / F2NonTsf や
523523
/// `mark_cold_raw_tsf`(`step_probe` 経由)から呼ぶ。
524524
pub(crate) fn gji_on_composition_reset(&mut self) {
525-
let resp = self
526-
.output
527-
.gji_on_event(crate::tsf::gji_fsm::GjiEvent::CompositionReset);
528-
self.dispatch_gji_response(resp);
525+
self.dispatch_gji_event(crate::tsf::gji_fsm::GjiEvent::CompositionReset);
529526
}
530527

531528
/// TSF mode で物理 F2 が消費されたことを GjiFsm に通知する(`on_reinject_key` の NativeF2Consumed パス)。
532529
///
533530
/// Medium/Long cold 中は probe が継続(saw_native_f2=true)。Short cold / OnWarm / OnComposing は
534531
/// CompositionReset 相当として処理される(GjiFsm 側で分岐)。
535532
pub(crate) fn gji_on_native_f2_consumed(&mut self) {
536-
let resp = self
537-
.output
538-
.gji_on_event(crate::tsf::gji_fsm::GjiEvent::NativeF2Consumed);
539-
self.dispatch_gji_response(resp);
533+
self.dispatch_gji_event(crate::tsf::gji_fsm::GjiEvent::NativeF2Consumed);
540534
}
541535

542536
/// GJI candidate SHOW → GjiFsm::StartComposition を dispatch する。
@@ -545,10 +539,7 @@ impl WindowsPlatform {
545539
/// `advance_tsf_probe` / `send_keys` で `take_pending_start_composition()` が true を返したときに呼ぶ。
546540
pub(crate) fn gji_on_start_composition(&mut self) {
547541
log::debug!("[gji-fsm] StartComposition (candidate SHOW)");
548-
let resp = self
549-
.output
550-
.gji_on_event(crate::tsf::gji_fsm::GjiEvent::StartComposition);
551-
self.dispatch_gji_response(resp);
542+
self.dispatch_gji_event(crate::tsf::gji_fsm::GjiEvent::StartComposition);
552543
}
553544

554545
/// GJI candidate HIDE → GjiFsm::EndComposition を dispatch する。
@@ -559,10 +550,7 @@ impl WindowsPlatform {
559550
pub(crate) fn gji_on_end_composition(&mut self) {
560551
if let Some(epoch) = self.output.gji_current_composition_epoch() {
561552
log::debug!("[gji-fsm] EndComposition (candidate HIDE) epoch={epoch:?}");
562-
let resp = self
563-
.output
564-
.gji_on_event(crate::tsf::gji_fsm::GjiEvent::EndComposition { epoch });
565-
self.dispatch_gji_response(resp);
553+
self.dispatch_gji_event(crate::tsf::gji_fsm::GjiEvent::EndComposition { epoch });
566554
}
567555
}
568556

crates/awase-windows/src/tsf/observer.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ pub(crate) fn gji_last_io_ms() -> u64 {
333333
TSF_OBS.gji_last_io_ms.load(Ordering::Relaxed)
334334
}
335335

336+
/// 現在時刻と最終 GJI I/O 時刻の差(アイドル時間)を ms で返す。
337+
pub(crate) fn gji_idle_ms() -> u64 {
338+
crate::hook::current_tick_ms().saturating_sub(gji_last_io_ms())
339+
}
340+
336341
/// GJI プロセスの最終 WriteOperationCount 変化時刻 (ms) を返す。0 = 未観測。live 読み取り。
337342
///
338343
/// 読み書き問わず更新される `gji_last_io_ms` と異なり、書き込みのみを追跡する。

0 commit comments

Comments
 (0)