mirror of
https://github.com/openai/codex.git
synced 2026-04-29 02:41:12 +03:00
132 lines
3.7 KiB
Markdown
132 lines
3.7 KiB
Markdown
**DOs**
|
||
|
||
- Bold: Debounce redraws via a request event: Introduce `RequestRedraw` and schedule `Redraw` after ~100 ms.
|
||
```rust
|
||
// app_event.rs
|
||
pub(crate) enum AppEvent {
|
||
// ...
|
||
RequestRedraw,
|
||
Redraw,
|
||
// ...
|
||
}
|
||
|
||
// app.rs
|
||
const REDRAW_DEBOUNCE: Duration = Duration::from_millis(100);
|
||
```
|
||
|
||
- Bold: Scope locks tightly: Lock only to check/set the pending flag, then drop it before spawning the worker.
|
||
```rust
|
||
fn schedule_redraw(&self) {
|
||
{
|
||
let mut flag = self.pending_redraw.lock().unwrap();
|
||
if *flag {
|
||
return;
|
||
}
|
||
*flag = true;
|
||
} // lock dropped here
|
||
|
||
let tx = self.app_event_tx.clone();
|
||
let pending_redraw = self.pending_redraw.clone();
|
||
std::thread::spawn(move || {
|
||
std::thread::sleep(REDRAW_DEBOUNCE);
|
||
tx.send(AppEvent::Redraw);
|
||
let mut f = pending_redraw.lock().unwrap();
|
||
*f = false;
|
||
});
|
||
}
|
||
```
|
||
|
||
- Bold: Prefer `.clone()` ergonomics: Clone `Arc`s and senders with `.clone()` before moving into threads.
|
||
```rust
|
||
let tx = self.app_event_tx.clone();
|
||
let pending_redraw = self.pending_redraw.clone();
|
||
std::thread::spawn(move || {
|
||
// use tx, pending_redraw here
|
||
});
|
||
```
|
||
|
||
- Bold: Convert producers to `RequestRedraw`: Replace direct `Redraw` sends in all producers.
|
||
```rust
|
||
// On startup
|
||
self.app_event_tx.clone().send(AppEvent::RequestRedraw);
|
||
|
||
// On terminal resize
|
||
crossterm::event::Event::Resize(_, _) => {
|
||
app_event_tx.send(AppEvent::RequestRedraw);
|
||
}
|
||
|
||
// Bottom pane / widgets
|
||
self.app_event_tx.send(AppEvent::RequestRedraw);
|
||
```
|
||
|
||
- Bold: Handle the request distinctly: Turn `RequestRedraw` into a debounced `Redraw` in the main loop.
|
||
```rust
|
||
while let Ok(event) = self.app_event_rx.recv() {
|
||
match event {
|
||
AppEvent::RequestRedraw => self.schedule_redraw(),
|
||
AppEvent::Redraw => self.draw_next_frame(terminal)?,
|
||
_ => {}
|
||
}
|
||
}
|
||
```
|
||
|
||
- Bold: Keep helpers near first use: Place `schedule_redraw` just above the match block that calls it for readability.
|
||
```rust
|
||
impl App<'_> {
|
||
// ... fields, new(), etc.
|
||
|
||
// place here (near run/loop)
|
||
fn schedule_redraw(&self) { /* as above */ }
|
||
|
||
pub(crate) fn run(&mut self, terminal: &mut tui::Tui, mouse_capture: &mut MouseCapture) -> Result<()> {
|
||
// uses schedule_redraw in match
|
||
}
|
||
}
|
||
```
|
||
|
||
**DON’Ts**
|
||
|
||
- Bold: Don’t hold locks across work: Avoid sleeping, sending, or spawning while a `MutexGuard` is alive.
|
||
```rust
|
||
// BAD: lock held far too long
|
||
fn schedule_redraw_bad(&self) {
|
||
let mut flag = self.pending_redraw.lock().unwrap();
|
||
if *flag { return; }
|
||
*flag = true;
|
||
|
||
std::thread::sleep(REDRAW_DEBOUNCE); // holding the lock
|
||
self.app_event_tx.send(AppEvent::Redraw); // still holding the lock
|
||
}
|
||
```
|
||
|
||
- Bold: Don’t emit `Redraw` directly from producers: Always send `RequestRedraw` so the app can debounce.
|
||
```rust
|
||
// BAD
|
||
app_event_tx.send(AppEvent::Redraw);
|
||
|
||
// GOOD
|
||
app_event_tx.send(AppEvent::RequestRedraw);
|
||
```
|
||
|
||
- Bold: Don’t reschedule when one is pending: Guard with a boolean to coalesce rapid requests.
|
||
```rust
|
||
// Inside schedule_redraw
|
||
let mut flag = self.pending_redraw.lock().unwrap();
|
||
if *flag { return; } // don't stack timers
|
||
*flag = true;
|
||
```
|
||
|
||
- Bold: Don’t bury relevant helpers: Avoid scattering debounce logic far from where events are handled.
|
||
```rust
|
||
// BAD: helper lives in a distant module/file, hard to follow
|
||
// GOOD: helper is defined in the same impl, just above its call sites
|
||
```
|
||
|
||
- Bold: Don’t prefer long-lived patterns when simple clones work: Use `.clone()` in place of `Arc::clone(&x)` when clarity is equal.
|
||
```rust
|
||
// Preferred here
|
||
let pending_redraw = self.pending_redraw.clone();
|
||
|
||
// Avoid when it adds noise
|
||
let pending_redraw = std::sync::Arc::clone(&self.pending_redraw); // noisier
|
||
``` |