Explorar o código

app/edit: improve perf of editing selection. only recalc rect when editing text itself (not select changes)

jkds hai 7 meses
pai
achega
7d589fd2ac

+ 1 - 7
bin/app/src/android/textinput/gametextinput.rs

@@ -185,13 +185,7 @@ impl GameTextInput {
         unsafe {
             let env = android::attach_jni_env();
             let jstate = self.state_to_java(state);
-            call_void_method!(
-                env,
-                input_connection,
-                "setState",
-                "(Ltextinput/State;)V",
-                jstate
-            );
+            call_void_method!(env, input_connection, "setState", "(Ltextinput/State;)V", jstate);
 
             let delete_local_ref = (**env).DeleteLocalRef.unwrap();
             delete_local_ref(env, jstate);

+ 2 - 0
bin/app/src/android/util.rs

@@ -32,5 +32,7 @@ unsafe fn check_except(env: *mut ndk_sys::JNIEnv, context: &str) {
 
         let exception_clear = (**env).ExceptionClear.unwrap();
         exception_clear(env);
+
+        panic!("Java exception detected in {context}");
     }
 }

+ 1 - 1
bin/app/src/text2/editor/android.rs

@@ -199,7 +199,7 @@ impl Editor {
     }
     pub fn selection(&self, side: isize) -> parley::Selection {
         assert!(side.abs() == 1);
-        t!("selection({side}) [state={:?}]", self.state);
+        //t!("selection({side}) [state={:?}]", self.state);
 
         let (start, end) = (self.state.select.0, self.state.select.1);
         let (anchor, focus) = match side {

+ 1 - 1
bin/app/src/ui/chatview/mod.rs

@@ -1003,7 +1003,7 @@ impl UIObject for ChatView {
         }
 
         let rect = self.rect.get();
-        t!("handle_touch({phase:?}, {id},{id},  {touch_pos:?})");
+        //t!("handle_touch({phase:?}, {id},{id},  {touch_pos:?})");
         let atom = &mut self.render_api.make_guard(gfxtag!("ChatView::handle_touch"));
 
         let touch_y = touch_pos.y;

+ 16 - 11
bin/app/src/ui/edit/mod.rs

@@ -857,7 +857,7 @@ impl BaseEdit {
         }
         true
     }
-    async fn handle_touch_end(&self, atom: &mut PropertyAtomicGuard, mut touch_pos: Point) -> bool {
+    async fn handle_touch_end(&self, mut touch_pos: Point) -> bool {
         //t!("handle_touch_end({touch_pos:?})");
         self.abs_to_local(&mut touch_pos);
 
@@ -865,6 +865,7 @@ impl BaseEdit {
         match state {
             TouchStateAction::Inactive => return false,
             TouchStateAction::Started { pos: _, instant: _ } | TouchStateAction::SetCursorPos => {
+                let atom = &mut self.render_api.make_guard(gfxtag!("BaseEdit::handle_touch_end"));
                 self.touch_set_cursor_pos(atom, touch_pos).await;
                 self.redraw(atom).await;
             }
@@ -980,7 +981,7 @@ impl BaseEdit {
 
             editor.selected_text()
         };
-        //d!("Select {seltext:?} from {clip_mouse_pos:?} (unclipped: {mouse_pos:?}) to ({sel_start}, {sel_end})");
+        //d!("Select {seltext:?} from {clip_mouse_pos:?} (unclipped: {mouse_pos:?})");
 
         // Android editor impl detail: selection disappears when anchor == index
         // But we disallow this so it should never happen. Just making a note of it here.
@@ -1047,6 +1048,7 @@ impl BaseEdit {
     }
 
     async fn redraw_select(&self, batch_id: BatchGuardId) {
+        //t!("redraw_select");
         let sel_instrs = self.regen_select_mesh().await;
         let phone_sel_instrs = self.regen_phone_select_handle_mesh().await;
         let draw_calls = vec![
@@ -1315,13 +1317,10 @@ impl BaseEdit {
 
         // Nothing changed. Just return.
         if !is_text_changed && !is_select_changed && !is_compose_changed {
-            t!("Skipping update since nothing changed");
+            //t!("Skipping update since nothing changed");
             return
         }
 
-        self.eval_rect().await;
-        self.behave.apply_cursor_scroll().await;
-
         //t!("is_text_changed={is_text_changed}, is_select_changed={is_select_changed}, is_compose_changed={is_compose_changed}");
         // Only redraw once we have the parent_rect
         // Can happen when we receive an Android event before the canvas is ready
@@ -1331,6 +1330,9 @@ impl BaseEdit {
 
         // Text changed - finish any active selection
         if is_text_changed || is_compose_changed {
+            self.eval_rect().await;
+            self.behave.apply_cursor_scroll().await;
+
             self.pause_blinking();
             //assert!(state.text != self.text.get());
             self.finish_select(atom);
@@ -1338,6 +1340,7 @@ impl BaseEdit {
         } else if is_select_changed {
             // Redrawing the entire text just for select changes is expensive
             self.redraw_cursor(atom.batch_id).await;
+            //t!("handle_android_event calling redraw_select");
             self.redraw_select(atom.batch_id).await;
         }
     }
@@ -1360,13 +1363,17 @@ impl UIObject for BaseEdit {
     fn init(&self) {
         let mut guard = self.editor.lock_blocking();
         assert!(guard.is_none());
-        *guard = Some(Editor::new(
+        let mut editor = Editor::new(
             self.text.clone(),
             self.font_size.clone(),
             self.text_color.clone(),
             self.window_scale.clone(),
             self.lineheight.clone(),
-        ));
+        );
+        let atom = &mut PropertyAtomicGuard::none();
+        self.text.set(atom, "the quick brown fox jumped over the");
+        smol::block_on(editor.on_text_prop_changed());
+        *guard = Some(editor);
     }
 
     async fn start(self: Arc<Self>, ex: ExecutorPtr) {
@@ -1758,12 +1765,10 @@ impl UIObject for BaseEdit {
             return false
         }
 
-        let atom = &mut self.render_api.make_guard(gfxtag!("BaseEdit::handle_touch"));
-
         match phase {
             TouchPhase::Started => self.handle_touch_start(touch_pos).await,
             TouchPhase::Moved => self.handle_touch_move(touch_pos).await,
-            TouchPhase::Ended => self.handle_touch_end(atom, touch_pos).await,
+            TouchPhase::Ended => self.handle_touch_end(touch_pos).await,
             TouchPhase::Cancelled => false,
         }
     }

+ 2 - 0
bin/app/src/ui/mod.rs

@@ -65,8 +65,10 @@ macro_rules! t { ($($arg:tt)*) => { trace!(target: "scene::on_modify", $($arg)*)
 pub trait UIObject: Sync {
     fn priority(&self) -> u32;
 
+    /// Called after schema and scenegraph is init but before miniquad starts.
     fn init(&self) {}
 
+    /// Done after miniquad has started and the first window draw has been done.
     async fn start(self: Arc<Self>, _ex: ExecutorPtr) {}
 
     /// Clear all buffers and caches