A simple CPU rendered GUI IDE experience.
force redraws
bendn 5 months ago
parent 48306e9 · commit 41513d7
-rw-r--r--src/lsp.rs12
-rw-r--r--src/main.rs45
-rw-r--r--src/winit_app.rs6
3 files changed, 38 insertions, 25 deletions
diff --git a/src/lsp.rs b/src/lsp.rs
index 3db71e7..e5b1ce3 100644
--- a/src/lsp.rs
+++ b/src/lsp.rs
@@ -35,6 +35,7 @@ pub struct Client {
pub initialized: Option<InitializeResult>,
// pub pending: HashMap<i32, oneshot::Sender<Re>>,
pub send_to: Sender<(i32, oneshot::Sender<Re>)>,
+ pub ch_tx: Sender<()>,
pub progress:
&'static papaya::HashMap<ProgressToken, Option<WorkDoneProgress>>,
pub not_rx: Receiver<N>,
@@ -134,6 +135,7 @@ impl Client {
},
)?;
let d = self.semantic_tokens.0;
+ let ch = self.ch_tx.clone();
let x = self.runtime.spawn(async move {
let x = rx.await?;
debug!("received semantic tokens");
@@ -145,6 +147,7 @@ impl Client {
SemanticTokensResult::Tokens(x) =>
d.store(x.data.into_boxed_slice().into()),
};
+ ch.send(())?;
anyhow::Ok(())
});
*p = Some((x, id));
@@ -159,14 +162,16 @@ pub fn run(
lsp_server::IoThreads,
),
workspace: WorkspaceFolder,
-) -> (Client, lsp_server::IoThreads, JoinHandle<()>) {
+) -> (Client, lsp_server::IoThreads, JoinHandle<()>, Receiver<()>) {
let now = Instant::now();
let (req_tx, req_rx) = unbounded();
let (not_tx, not_rx) = unbounded();
let (_req_tx, _req_rx) = unbounded();
+ let (ch_tx, ch_rx) = unbounded();
let mut c = Client {
tx,
req_rx: _req_rx,
+ ch_tx: ch_tx.clone(),
progress: Box::leak(Box::new(papaya::HashMap::new())),
runtime: tokio::runtime::Builder::new_multi_thread()
.thread_name("lsp runtime")
@@ -337,6 +342,7 @@ pub fn run(
Ok(Message::Notification(x @ N { method: "$/progress", .. })) => {
let ProgressParams {token,value:ProgressParamsValue::WorkDone(x) } = x.load::<Progress>().unwrap();
progress.update(token, move |_| Some(x.clone()), &progress.guard());
+ _ = ch_tx.send(());
}
Ok(Message::Notification(notification)) => {
debug!("rx {notification:?}");
@@ -349,7 +355,7 @@ pub fn run(
}
}
});
- (c, iot, h)
+ (c, iot, h, ch_rx)
}
pub fn x() {
@@ -362,7 +368,7 @@ pub fn x() {
log::info!("helol");
- let (c, rx, iot) = run(
+ let (c, rx, iot, ch) = run(
lsp_server::stdio::stdio_transport(
BufReader::new(c.stdout.take().unwrap()),
c.stdin.take().unwrap(),
diff --git a/src/main.rs b/src/main.rs
index 7e88278..698acf4 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4,6 +4,7 @@
mpmc_channel,
const_cmp,
const_default,
+ cell_get_cloned,
import_trait_associated_functions,
if_let_guard,
deref_patterns,
@@ -18,7 +19,9 @@ use std::io::BufReader;
use std::num::NonZeroU32;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
-use std::sync::LazyLock;
+use std::rc::Rc;
+use std::sync::{Arc, LazyLock, OnceLock};
+use std::thread;
use std::time::Instant;
use Default::default;
@@ -32,6 +35,7 @@ use lsp_types::{
ServerCapabilities, TextDocumentIdentifier,
TextDocumentPositionParams, WorkspaceFolder,
};
+use parking_lot::RwLock;
use regex::Regex;
use ropey::Rope;
use rust_fsm::StateMachineImpl;
@@ -43,7 +47,7 @@ use winit::event::{
use winit::event_loop::{ControlFlow, EventLoop};
use winit::keyboard::{Key, ModifiersState, NamedKey, SmolStr};
use winit::platform::wayland::WindowAttributesExtWayland;
-use winit::window::Icon;
+use winit::window::{Icon, Window};
use crate::bar::Bar;
use crate::text::{Diff, TextArea};
@@ -183,7 +187,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
.spawn()
.unwrap();
- let (c, t, t2) = lsp::run(
+ let (c, t, t2, changed) = lsp::run(
lsp_server::stdio::stdio_transport(
BufReader::new(c.stdout.take().unwrap()),
c.stdin.take().unwrap(),
@@ -199,9 +203,14 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
);
c.open(&origin, std::fs::read_to_string(&origin).unwrap())
.unwrap();
- ((c, origin), (t, t2))
+ ((c, origin), (t, t2), changed)
});
- let (lsp, t) = c.unzip();
+ let (lsp, t, ch) = match c {
+ Some((a,b,c)) => {
+ (Some(a), Some(b), Some(c))
+ },
+ None => { (None, None, None) }
+ };
// let mut hl_result = None;
@@ -240,8 +249,9 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
mtime = modify!();
}};
}
+ static PUT: OnceLock<Arc<Window>> = OnceLock::new();
let app = winit_app::WinitAppBuilder::with_init(
- |elwt| {
+ move |elwt| {
let window = winit_app::make_window(elwt, |x| {
x.with_title("gracilaria")
.with_name("com.bendn.gracilaria", "")
@@ -249,7 +259,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
});
window.set_ime_allowed(true);
window.set_ime_purpose(winit::window::ImePurpose::Terminal);
-
+ PUT.set(window.clone()).unwrap();
let context =
softbuffer::Context::new(window.clone()).unwrap();
@@ -275,8 +285,10 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
if modify!() != mtime {
mtime = modify!();
state.consume(Action::Changed).unwrap();
+ window.request_redraw();
}
match event {
+ Event::AboutToWait => {}
Event::WindowEvent {
window_id,
event: WindowEvent::Resized(size),
@@ -399,10 +411,6 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
&text,
lsp.as_ref().map(|x| &x.0)
);
-
- println!("cell=");
- dbg!(now.elapsed());
- let now = Instant::now();
unsafe {
dsb::render(
&cells,
@@ -415,11 +423,8 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
i.as_mut(),
)
};
- // eprint!("rend=");
- // dbg!(now.elapsed());
let met = FONT.metrics(&[]);
let fac = ppem / met.units_per_em as f32;
- let now = Instant::now();
// if x.view_o == Some(x.cells.row) || x.view_o.is_none() {
use fimg::OverlayAt;
@@ -449,9 +454,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
);
}
};
- // eprint!("conv = ");
- // }
let buffer = surface.buffer_mut().unwrap();
let x = unsafe {
std::slice::from_raw_parts_mut(
@@ -461,7 +464,7 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
.as_chunks_unchecked_mut::<4>()
};
fimg::overlay::copy_rgb_bgr_(i.flatten(), x);
- // dbg!(now.elapsed());
+ dbg!(now.elapsed());
buffer.present().unwrap();
}
}
@@ -757,8 +760,12 @@ pub(crate) fn entry(event_loop: EventLoop<()>) {
_ => {}
};
},
- );
-
+ );
+ ch.map(|ch| thread::spawn(move || {
+ for () in ch {
+ PUT.get().map(|x| x.request_redraw());
+ }
+ }));
winit_app::run_app(event_loop, app);
}
diff --git a/src/winit_app.rs b/src/winit_app.rs
index 12fbfce..2d8c528 100644
--- a/src/winit_app.rs
+++ b/src/winit_app.rs
@@ -1,6 +1,6 @@
/// Common boilerplate for setting up a winit application.
use std::marker::PhantomData;
-use std::rc::Rc;
+use std::sync::Arc;
use winit::application::ApplicationHandler;
use winit::event::{Event, WindowEvent};
@@ -25,7 +25,7 @@ pub(crate) fn run_app(
pub(crate) fn make_window(
elwt: &ActiveEventLoop,
f: impl FnOnce(WindowAttributes) -> WindowAttributes,
-) -> Rc<Window> {
+) -> Arc<Window> {
let attributes = f(WindowAttributes::default());
#[cfg(target_arch = "wasm32")]
let attributes =
@@ -33,7 +33,7 @@ pub(crate) fn make_window(
attributes, true,
);
let window = elwt.create_window(attributes);
- Rc::new(window.unwrap())
+ Arc::new(window.unwrap())
}
/// Easily constructable winit application.