Просмотр исходного кода

app: use thread local non-locking storage for text context

darkfi 1 год назад
Родитель
Сommit
89826d5071

+ 3 - 0
bin/app/Makefile

@@ -86,6 +86,9 @@ apk: $(SRC) fonts
 cli:
 	podman run -v $(shell pwd)/../../:/root/darkfi -w /root/darkfi/bin/app/ -it apk bash
 
+fmt:
+	$(CARGO) +nightly fmt
+
 clean:
 	podman run -v $(shell pwd):/root/dw -w /root/dw -t apk rm -fr target/
 	rm -f darkfi-app.apk

+ 1 - 3
bin/app/src/mesh.rs

@@ -89,9 +89,7 @@ impl MeshBuilder {
     pub fn draw_box(&mut self, obj: &Rectangle, color: Color, uv: &Rectangle) {
         let clipped = match &self.clipper {
             Some(clipper) => {
-                let Some(clipped) = clipper.clip(&obj) else {
-                    return
-                };
+                let Some(clipped) = clipper.clip(&obj) else { return };
                 clipped
             }
             None => obj.clone(),

+ 4 - 8
bin/app/src/text2/editor/android.rs

@@ -123,12 +123,6 @@ impl Editor {
         let lineheight = self.lineheight.get();
         let edit = android::get_editable(self.composer_id).unwrap();
 
-        //let buffer = android::get_raw_text(self.composer_id).unwrap();
-        //let sel_start = android::get_selection_start(self.composer_id).unwrap();
-        //let sel_end = android::get_selection_end(self.composer_id).unwrap();
-        //if sel_start != sel_end || sel_start < 0 {
-        //    return None
-        //}
         let cursor_byte_idx = char16_to_byte_index(&edit.buffer, edit.select_start).unwrap();
 
         let cursor = if cursor_byte_idx >= edit.buffer.len() {
@@ -150,7 +144,9 @@ impl Editor {
         Some(cursor_pos)
     }
 
-    pub async fn driver<'a>(&'a mut self) -> Option<parley::PlainEditorDriver<'a, Color>> {
-        None
+    pub fn driver<F>(&mut self, f: F)
+    where
+        F: FnOnce(&mut parley::PlainEditorDriver<'_, Color>),
+    {
     }
 }

+ 14 - 37
bin/app/src/text2/editor/parley.rs

@@ -20,7 +20,7 @@ use crate::{
     gfx::Point,
     mesh::Color,
     prop::{PropertyColor, PropertyFloat32},
-    text2::{get_ctx, TextContext, FONT_STACK},
+    text2::{TextContext, FONT_STACK, TEXT_CTX2},
 };
 
 macro_rules! t { ($($arg:tt)*) => { trace!(target: "text::editor", $($arg)*); } }
@@ -63,9 +63,10 @@ impl Editor {
         styles.insert(parley::StyleProperty::Brush(text_color));
         *self.editor.edit_styles() = styles;
 
-        let mut txt_ctx = get_ctx().await;
-        let (font_ctx, layout_ctx) = txt_ctx.borrow();
-        self.editor.refresh_layout(font_ctx, layout_ctx);
+        TEXT_CTX2.with_borrow_mut(|txt_ctx| {
+            let (font_ctx, layout_ctx) = txt_ctx.borrow();
+            self.editor.refresh_layout(font_ctx, layout_ctx);
+        });
     }
 
     pub fn layout(&self) -> &parley::Layout<Color> {
@@ -81,38 +82,14 @@ impl Editor {
         Some(cursor_pos)
     }
 
-    pub async fn driver<'a>(&'a mut self) -> Option<DriverWrapper<'a>> {
-        let mut txt_ctx = get_ctx().await;
-        // I'm one billion percent sure this is safe and don't want to waste time
-        let (font_ctx, layout_ctx) = {
-            let (f, l) = txt_ctx.borrow();
-            let f: &'a mut parley::FontContext = unsafe { std::mem::transmute(f) };
-            let l: &'a mut parley::LayoutContext<Color> = unsafe { std::mem::transmute(l) };
-            (f, l)
-        };
-        let drv = self.editor.driver(font_ctx, layout_ctx);
-        // Storing the MutexGuard together with its dependent value drv ensures we cannot
-        // have a race condition and the lifetime rules are respected.
-        let drv = DriverWrapper { txt_ctx, drv };
-        Some(drv)
-    }
-}
-
-pub struct DriverWrapper<'a> {
-    txt_ctx: async_lock::MutexGuard<'static, TextContext>,
-    drv: parley::PlainEditorDriver<'a, Color>,
-}
-
-impl<'a> std::ops::Deref for DriverWrapper<'a> {
-    type Target = parley::PlainEditorDriver<'a, Color>;
-
-    fn deref(&self) -> &Self::Target {
-        &self.drv
-    }
-}
-
-impl<'a> std::ops::DerefMut for DriverWrapper<'a> {
-    fn deref_mut(&mut self) -> &mut Self::Target {
-        &mut self.drv
+    pub fn driver<F>(&mut self, f: F)
+    where
+        F: FnOnce(parley::PlainEditorDriver<'_, Color>),
+    {
+        TEXT_CTX2.with_borrow_mut(|txt_ctx| {
+            let (font_ctx, layout_ctx) = txt_ctx.borrow();
+            let drv = self.editor.driver(font_ctx, layout_ctx);
+            f(drv);
+        });
     }
 }

+ 8 - 1
bin/app/src/text2/mod.rs

@@ -17,7 +17,10 @@
  */
 
 use async_lock::Mutex as AsyncMutex;
-use std::sync::{Arc, OnceLock};
+use std::{
+    cell::RefCell,
+    sync::{Arc, OnceLock},
+};
 
 use crate::mesh::Color;
 
@@ -27,6 +30,10 @@ pub use editor::Editor;
 mod render;
 pub use render::{render_layout, DebugRenderOptions};
 
+thread_local! {
+    static TEXT_CTX2: RefCell<TextContext> = RefCell::new(TextContext::new());
+}
+
 static TEXT_CTX: OnceLock<AsyncMutex<TextContext>> = OnceLock::new();
 
 pub async fn get_ctx() -> async_lock::MutexGuard<'static, TextContext> {

+ 1 - 2
bin/app/src/ui/chatedit.rs

@@ -539,8 +539,7 @@ impl ChatEdit {
         let key_str = key.encode_utf8(&mut tmp);
 
         let mut editor = self.editor.lock().await;
-        let mut drv = editor.driver().await.unwrap();
-        drv.insert_or_replace_selection(&key_str);
+        editor.driver(|mut drv| drv.insert_or_replace_selection(&key_str));
     }
 
     async fn handle_shortcut(